Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.77% covered (success)
90.77%
59 / 65
50.00% covered (warning)
50.00%
3 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Imagick
90.77% covered (success)
90.77%
59 / 65
50.00% covered (warning)
50.00%
3 / 6
26.53
0.00% covered (danger)
0.00%
0 / 1
 border
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 fill
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 radialGradient
89.47% covered (success)
89.47%
17 / 19
0.00% covered (danger)
0.00%
0 / 1
6.04
 verticalGradient
86.67% covered (success)
86.67%
13 / 15
0.00% covered (danger)
0.00%
0 / 1
6.09
 horizontalGradient
87.50% covered (success)
87.50%
14 / 16
0.00% covered (danger)
0.00%
0 / 1
6.07
 linearGradient
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <dev@noladev.com>
8 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Image\Effect;
16
17use Pop\Color\Color;
18use ImagickException;
19
20/**
21 * Effect class for Imagick
22 *
23 * @category   Pop
24 * @package    Pop\Image
25 * @author     Nick Sagona, III <dev@noladev.com>
26 * @copyright  Copyright (c) 2009-2027 NOLA Interactive, LLC.
27 * @license    https://www.popphp.org/license     New BSD License
28 * @version    5.0.0
29 */
30class Imagick extends AbstractEffect
31{
32
33    /**
34     * Draw a border around the image.
35     *
36     * @param  Color\ColorInterface $color
37     * @param  int|float            $w
38     * @param  int|float|null       $h
39     * @return Imagick
40     */
41    public function border(Color\ColorInterface $color, int|float $w = 1, int|float|null $h = null): Imagick
42    {
43        if ($this->hasImage()) {
44            $h = ($h === null) ? $w : $h;
45            $this->image->getResource()->borderImage($this->image->createColor($color), $w, $h);
46        }
47        return $this;
48    }
49
50    /**
51     * Flood the image with a color fill.
52     *
53     * @param  Color\ColorInterface $color
54     * @return Imagick
55     */
56    public function fill(Color\ColorInterface $color): Imagick
57    {
58        if ($this->hasImage()) {
59            $draw = new \ImagickDraw();
60            $draw->setFillColor($this->image->createColor($color));
61            $draw->rectangle(0, 0, $this->image->getWidth(), $this->image->getHeight());
62            $this->image->getResource()->drawImage($draw);
63        }
64        return $this;
65    }
66
67    /**
68     * Flood the image with a vertical color gradient.
69     *
70     * @param  Color\ColorInterface $color1
71     * @param  Color\ColorInterface $color2
72     * @throws ImagickException|Exception
73     * @return Imagick
74     */
75    public function radialGradient(Color\ColorInterface $color1, Color\ColorInterface $color2): Imagick
76    {
77        if ($this->hasImage()) {
78            $im = new \Imagick();
79            $width = (int)round($this->image->getWidth() * 1.25);
80            $height = (int)round($this->image->getHeight() * 1.25);
81
82            if (!($color1 instanceof Color\Rgb)) {
83                if (!method_exists($color1, 'toRgb')) {
84                    throw new Exception('Error: The color object does not support conversion to RGB.');
85                }
86                $color1 = $color1->toRgb();
87            }
88            if (!($color2 instanceof Color\Rgb)) {
89                if (!method_exists($color2, 'toRgb')) {
90                    throw new Exception('Error: The color object does not support conversion to RGB.');
91                }
92                $color2 = $color2->toRgb();
93            }
94
95            $im->newPseudoImage($width, $height, 'radial-gradient:' . $color1->toHex() . '-' . $color2->toHex());
96            $this->image->getResource()->compositeImage(
97                $im, \Imagick::COMPOSITE_ATOP,
98                0 - (int)round(($width - $this->image->getWidth()) / 2),
99                0 - (int)round(($height - $this->image->getHeight()) / 2)
100            );
101        }
102
103        return $this;
104    }
105
106    /**
107     * Flood the image with a vertical color gradient.
108     *
109     * @param  Color\ColorInterface $color1
110     * @param  Color\ColorInterface $color2
111     * @throws ImagickException|Exception
112     * @return Imagick
113     */
114    public function verticalGradient(Color\ColorInterface $color1, Color\ColorInterface $color2): Imagick
115    {
116        if ($this->hasImage()) {
117            $im = new \Imagick();
118
119            if (!($color1 instanceof Color\Rgb)) {
120                if (!method_exists($color1, 'toRgb')) {
121                    throw new Exception('Error: The color object does not support conversion to RGB.');
122                }
123                $color1 = $color1->toRgb();
124            }
125            if (!($color2 instanceof Color\Rgb)) {
126                if (!method_exists($color2, 'toRgb')) {
127                    throw new Exception('Error: The color object does not support conversion to RGB.');
128                }
129                $color2 = $color2->toRgb();
130            }
131
132            $im->newPseudoImage(
133                $this->image->getWidth(), $this->image->getHeight(), 'gradient:' . $color1->toHex() . '-' . $color2->toHex()
134            );
135            $this->image->getResource()->compositeImage($im, \Imagick::COMPOSITE_ATOP, 0, 0);
136        }
137
138        return $this;
139    }
140
141    /**
142     * Flood the image with a vertical color gradient.
143     *
144     * @param  Color\ColorInterface $color1
145     * @param  Color\ColorInterface $color2
146     * @throws ImagickException|Exception
147     * @return Imagick
148     */
149    public function horizontalGradient(Color\ColorInterface $color1, Color\ColorInterface $color2): Imagick
150    {
151        if ($this->hasImage()) {
152            $im = new \Imagick();
153
154            if (!($color1 instanceof Color\Rgb)) {
155                if (!method_exists($color1, 'toRgb')) {
156                    throw new Exception('Error: The color object does not support conversion to RGB.');
157                }
158                $color1 = $color1->toRgb();
159            }
160            if (!($color2 instanceof Color\Rgb)) {
161                if (!method_exists($color2, 'toRgb')) {
162                    throw new Exception('Error: The color object does not support conversion to RGB.');
163                }
164                $color2 = $color2->toRgb();
165            }
166
167            $im->newPseudoImage(
168                $this->image->getHeight(), $this->image->getWidth(), 'gradient:' . $color1->toHex() . '-' . $color2->toHex()
169            );
170            $im->rotateImage('rgb(255, 255, 255)', -90);
171            $this->image->getResource()->compositeImage($im, \Imagick::COMPOSITE_ATOP, 0, 0);
172        }
173
174        return $this;
175    }
176
177    /**
178     * Flood the image with a color gradient.
179     *
180     * @param  Color\ColorInterface $color1
181     * @param  Color\ColorInterface $color2
182     * @param  bool                 $vertical
183     * @throws ImagickException
184     * @return Imagick
185     */
186    public function linearGradient(Color\ColorInterface $color1, Color\ColorInterface $color2, bool $vertical = true): Imagick
187    {
188        if ($this->hasImage()) {
189            if ($vertical) {
190                $this->verticalGradient($color1, $color2);
191            } else {
192                $this->horizontalGradient($color1, $color2);
193            }
194        }
195
196        return $this;
197    }
198
199}