Passed
Push — master ( 8718bd...547bf2 )
by compolom
02:24
created

Imagick::tmp()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

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