Passed
Branch next (340ec9)
by compolom
03:46
created

Imagick2::setSizes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Compolomus\Compomage;
4
5
use Compolomus\Compomage\Interfaces\ImageInterface;
6
use Exception;
7
use imagick;
8
use ImagickDraw;
9
use ImagickException;
10
use ImagickPixel;
11
use InvalidArgumentException;
12
13
class Imagick2 extends AbstractImage
14
{
15
    /**
16
     * Imagick constructor.
17
     * @param string $image
18
     * @throws Exception
19
     */
20 9
    public function __construct(string $image)
21
    {
22 9
        $this->init($image);
23 9
    }
24
25
    /**
26
     * @param int $width
27
     * @param int $height
28
     * @return ImageInterface
29
     * @throws ImagickException
30
     */
31 1
    public function resize(int $width, int $height): ImageInterface
32
    {
33 1
        $this->getImage()->scaleImage($width, $height, false);
34 1
        $this->setSizes();
35
36 1
        return $this;
37
    }
38
39 9
    protected function setSizes(): void
40
    {
41 9
        $args = $this->getImage()->getImageGeometry();
42 9
        $this->setWidth($args['width']);
43 9
        $this->setHeight($args['height']);
44 9
        $this->setOrientation();
45 9
    }
46
47
    /**
48
     * @param int $angle
49
     * @return ImageInterface
50
     */
51 1
    public function rotate(int $angle = 90): ImageInterface
52
    {
53 1
        $this->getImage()->rotateImage(new ImagickPixel('transparent'), $angle);
54 1
        $this->setSizes();
55
56 1
        return $this;
57
    }
58
59
    /**
60
     * @return ImageInterface
61
     */
62
    public function flip(): ImageInterface
63
    {
64
        $this->getImage()->flipImage();
65
66
        return $this;
67
    }
68
69
    /**
70
     * @return ImageInterface
71
     */
72
    public function flop(): ImageInterface
73
    {
74
        $this->getImage()->flopImage();
75
76
        return $this;
77
    }
78
79
    public function grayscale(): ImageInterface
80
    {
81
        $this->getImage()->transformimagecolorspace(Imagick::COLORSPACE_GRAY);
82
        $this->getImage()->separateImageChannel(1);
83
84
        return $this;
85
    }
86
87
    /**
88
     * @param string $text
89
     * @param string $position
90
     * @param string $font
91
     * @return ImageInterface
92
     * @throws InvalidArgumentException
93
     * @throws ImagickException
94
     */
95 1
    public function copyright(string $text, string $font = 'Courier', string $position = 'SouthWest'): ImageInterface
96
    {
97
        $positions = [
98 1
            'NORTHWEST' => Imagick::GRAVITY_NORTHWEST,
99
            'NORTH' => Imagick::GRAVITY_NORTH,
100
            'NORTHEAST' => Imagick::GRAVITY_NORTHEAST,
101
            'WEST' => Imagick::GRAVITY_WEST,
102
            'CENTER' => Imagick::GRAVITY_CENTER,
103
            'SOUTHWEST' => Imagick::GRAVITY_SOUTHWEST,
104
            'SOUTH' => Imagick::GRAVITY_SOUTH,
105
            'SOUTHEAST' => Imagick::GRAVITY_SOUTHEAST,
106
            'EAST' => Imagick::GRAVITY_EAST
107
        ];
108 1
        if (!array_key_exists(strtoupper($position), $positions) || !in_array($font, $this->getFontsList(), true)) {
109 1
            throw new InvalidArgumentException('Does not support font or wrong position');
110
        }
111
        $this->getImage()->compositeImage($this->prepareImage($text, $positions[strtoupper($position)], $font),
112
            Imagick::COMPOSITE_DISSOLVE, 0, 0);
113
114
        return $this;
115
    }
116
117 1
    public function getFontsList(): array
118
    {
119 1
        return $this->getImage()->queryFonts();
120
    }
121
122
    /**
123
     * @param string $text
124
     * @param int $position
125
     * @param string $font
126
     * @return Imagick
127
     * @throws ImagickException
128
     */
129
    private function prepareImage(string $text, int $position, string $font): Imagick
130
    {
131
        $image = new Imagick();
132
        $mask = new Imagick();
133
        $draw = new ImagickDraw();
134
        $image->newImage($this->getWidth(), $this->getHeight(), new ImagickPixel('grey30'));
135
        $mask->newImage($this->getWidth(), $this->getHeight(), new ImagickPixel('black'));
136
        $draw->setFont($font);
137
        $draw->setFontSize(20);
138
        $draw->setFillColor(new ImagickPixel('grey70'));
139
        $draw->setGravity($position);
140
        $image->annotateImage($draw, 10, 12, 0, $text);
141
        $draw->setFillColor(new ImagickPixel('white'));
142
        $mask->annotateImage($draw, 11, 13, 0, $text);
143
        $mask->annotateImage($draw, 10, 12, 0, $text);
144
        $draw->setFillColor(new ImagickPixel('black'));
145
        $mask->annotateImage($draw, 9, 11, 0, $text);
146
        $mask->setImageMatte(false);
147
        $image->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0);
148
149
        return $image;
150
    }
151
152
    /**
153
     * @param int $width
154
     * @param int $height
155
     * @param int $startX
156
     * @param int $startY
157
     * @return ImageInterface
158
     */
159
    public function crop(int $width, int $height, int $startX, int $startY): ImageInterface
160
    {
161
        $this->getImage()->cropImage($width, $height, $startX, $startY);
162
        $this->setSizes();
163
164
        return $this;
165
    }
166
167 1
    public function save(string $filename, $quality = 100): bool
168
    {
169 1
        $this->getImage()->setImageCompressionQuality($quality);
170 1
        $this->getImage()->writeImage($filename . '.png');
171
172 1
        return true;
173
    }
174
175 1
    public function __toString(): string
176
    {
177 1
        return trim($this->getImage()->getImageBlob());
178
    }
179
180
    /**
181
     * @param int $width
182
     * @param int $height
183
     * @return ImageInterface
184
     * @throws ImagickException
185
     */
186 1
    protected function prepareThumbnail(int $width, int $height): ImageInterface
187
    {
188 1
        $this->getImage()->cropThumbnailImage($width, $height);
189
190 1
        return $this;
191
    }
192
193
    /**
194
     * @param string $source
195
     * @return ImageInterface
196
     * @throws ImagickException
197
     */
198 9
    protected function tmp(string $source): ImageInterface
199
    {
200 9
        $image = new Imagick;
201 9
        if ($image->readImageBlob($source)) {
202 9
            if ($image->getImageAlphaChannel() !== Imagick::ALPHACHANNEL_ACTIVATE) {
203 8
                $image->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);
204
            }
205
        }
206 9
        $background = $this->newImage($image->getImageWidth(), $image->getImageHeight());
207 9
        $image->compositeImage($background, Imagick::COMPOSITE_OVER, 0, 0); //Imagick::COMPOSITE_DISSOLVE
208 9
        $this->setImage($image);
209 9
        $this->getImage()->setFormat('png'); // save transparent
210 9
        $this->setSizes();
211
212 9
        return $this;
213
    }
214
215
    /**
216
     * @param int $width
217
     * @param int $height
218
     * @return Imagick
219
     * @throws ImagickException
220
     */
221 9
    protected function newImage(int $width, int $height): Imagick
222
    {
223 9
        $background = new Imagick;
224 9
        $background->newImage($width, $height, new ImagickPixel('transparent'));
225 9
        $background->setImageBackgroundColor(new ImagickPixel('transparent'));
226
227 9
        return $background;
228
    }
229
230
    /**
231
     * @param Image $watermark
232
     * @param int $x
233
     * @param int $y
234
     * @return ImageInterface
235
     * @throws Exception
236
     */
237
    protected function prepareWatermark($watermark, int $x, int $y): ImageInterface
238
    {
239
        $watermark->getImage()->evaluateImage(Imagick::EVALUATE_MULTIPLY, 1, Imagick::CHANNEL_ALPHA);
240
        $this->getImage()->compositeImage($watermark->getImage(), Imagick::COMPOSITE_DISSOLVE, $x, $y);
241
242
        return $this;
243
    }
244
245
    public function resizeByTransparentBackground(int $width, int $height): ImageInterface
246
    {
247
        // TODO: Implement resizeByTransparentBackground() method.
248
        return $this;
249
    }
250
251
    public function resizeByBlurBackground(int $width, int $height): ImageInterface
252
    {
253
        // TODO: Implement resizeByBlurBackground() method.
254
        return $this;
255
    }
256
}
257