1 | <?php declare(strict_types=1); |
||
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 | public function __construct(string $image) |
||
21 | { |
||
22 | $this->init($image); |
||
23 | } |
||
24 | |||
25 | /** |
||
26 | * @param int $width |
||
27 | * @param int $height |
||
28 | * @return ImageInterface |
||
29 | * @throws \ImagickException |
||
30 | */ |
||
31 | public function resize(int $width, int $height): ImageInterface |
||
32 | { |
||
33 | $this->getImage()->scaleImage($width, $height, false); |
||
34 | $this->setSizes(); |
||
35 | |||
36 | return $this; |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * @return \Imagick |
||
41 | */ |
||
42 | public function getImage(): \Imagick |
||
43 | { |
||
44 | return $this->image; |
||
45 | } |
||
46 | |||
47 | public function setImage($image): void |
||
48 | { |
||
49 | $this->image = $image; |
||
50 | } |
||
51 | |||
52 | protected function setSizes(): void |
||
53 | { |
||
54 | $args = $this->getImage()->getImageGeometry(); |
||
55 | $this->setWidth($args['width']); |
||
56 | $this->setHeight($args['height']); |
||
57 | } |
||
58 | |||
59 | /** |
||
60 | * @param int $angle |
||
61 | * @return ImageInterface |
||
62 | */ |
||
63 | public function rotate(int $angle = 90): ImageInterface |
||
64 | { |
||
65 | $this->getImage()->rotateImage(new \ImagickPixel('transparent'), $angle); |
||
66 | $this->setSizes(); |
||
67 | |||
68 | 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()->modulateImage(100, 0, 100); |
||
94 | |||
95 | return $this; |
||
96 | } |
||
97 | |||
98 | /** |
||
99 | * @param string $text |
||
100 | * @param string $position |
||
101 | * @param string $font |
||
102 | * @return $this |
||
103 | * @throws \Exception |
||
104 | */ |
||
105 | public function copyright(string $text, string $font = 'Courier', string $position = 'SouthWest'): ImageInterface |
||
106 | { |
||
107 | $positions = [ |
||
108 | 'NORTHWEST' => \Imagick::GRAVITY_NORTHWEST, |
||
109 | 'NORTH' => \Imagick::GRAVITY_NORTH, |
||
110 | 'NORTHEAST' => \Imagick::GRAVITY_NORTHEAST, |
||
111 | 'WEST' => \Imagick::GRAVITY_WEST, |
||
112 | 'CENTER' => \Imagick::GRAVITY_CENTER, |
||
113 | 'SOUTHWEST' => \Imagick::GRAVITY_SOUTHWEST, |
||
114 | 'SOUTH' => \Imagick::GRAVITY_SOUTH, |
||
115 | 'SOUTHEAST' => \Imagick::GRAVITY_SOUTHEAST, |
||
116 | 'EAST' => \Imagick::GRAVITY_EAST |
||
117 | ]; |
||
118 | if (!array_key_exists(strtoupper($position), $positions) || !\in_array($font, $this->getFontsList(), true)) { |
||
119 | throw new \InvalidArgumentException('Does not support font or wrong position'); |
||
120 | } |
||
121 | $this->getImage()->compositeImage($this->prepareImage($text, $positions[strtoupper($position)], $font), |
||
122 | \Imagick::COMPOSITE_DISSOLVE, 0, 0); |
||
123 | |||
124 | return $this; |
||
125 | } |
||
126 | |||
127 | public function getFontsList(): array |
||
128 | { |
||
129 | return $this->getImage()->queryFonts(); |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * @param string $text |
||
134 | * @param int $position |
||
135 | * @param string $font |
||
136 | * @return \Imagick |
||
137 | * @throws \ImagickException |
||
138 | */ |
||
139 | private function prepareImage(string $text, int $position, string $font): \Imagick |
||
140 | { |
||
141 | $image = new \Imagick(); |
||
142 | $mask = new \Imagick(); |
||
143 | $draw = new \ImagickDraw(); |
||
144 | $image->newImage($this->getWidth(), $this->getHeight(), new \ImagickPixel('grey30')); |
||
145 | $mask->newImage($this->getWidth(), $this->getHeight(), new \ImagickPixel('black')); |
||
146 | $draw->setFont($font); |
||
147 | $draw->setFontSize(20); |
||
148 | $draw->setFillColor(new \ImagickPixel('grey70')); |
||
149 | $draw->setGravity($position); |
||
150 | $image->annotateImage($draw, 10, 12, 0, $text); |
||
151 | $draw->setFillColor(new \ImagickPixel('white')); |
||
152 | $mask->annotateImage($draw, 11, 13, 0, $text); |
||
153 | $mask->annotateImage($draw, 10, 12, 0, $text); |
||
154 | $draw->setFillColor(new \ImagickPixel('black')); |
||
155 | $mask->annotateImage($draw, 9, 11, 0, $text); |
||
156 | $mask->setImageMatte(false); |
||
157 | $image->compositeImage($mask, \Imagick::COMPOSITE_COPYOPACITY, 0, 0); |
||
158 | |||
159 | return $image; |
||
160 | } |
||
161 | |||
162 | /** |
||
163 | * @param int $width |
||
164 | * @param int $height |
||
165 | * @param int $startX |
||
166 | * @param int $startY |
||
167 | * @return ImageInterface |
||
168 | */ |
||
169 | public function crop(int $width, int $height, int $startX, int $startY): ImageInterface |
||
170 | { |
||
171 | $this->getImage()->cropImage($width, $height, $startX, $startY); |
||
172 | $this->setSizes(); |
||
173 | |||
174 | return $this; |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * @param int $width |
||
179 | * @param int $height |
||
180 | * @return ImageInterface |
||
181 | * @throws \ImagickException |
||
182 | */ |
||
183 | protected function prepareThumbnail(int $width, int $height): ImageInterface { |
||
184 | $this->getImage()->cropThumbnailImage($width, $height); |
||
185 | |||
186 | return $this; |
||
187 | } |
||
188 | |||
189 | public function save(string $filename): bool |
||
193 | |||
194 | public function __toString(): string |
||
198 | |||
199 | /** |
||
200 | * @param string $source |
||
201 | * @return ImageInterface |
||
202 | * @throws \Exception |
||
203 | */ |
||
204 | protected function tmp(string $source): ImageInterface |
||
205 | { |
||
206 | $image = new \Imagick; |
||
207 | if ($image->readImageBlob($source)) { |
||
208 | if ($image->getImageAlphaChannel() !== \Imagick::ALPHACHANNEL_ACTIVATE) { |
||
209 | $image->setImageAlphaChannel(\Imagick::ALPHACHANNEL_SET); |
||
210 | } |
||
211 | } |
||
212 | $background = $this->newImage($image->getImageWidth(), $image->getImageHeight()); |
||
220 | |||
221 | /** |
||
222 | * @param int $width |
||
223 | * @param int $height |
||
224 | * @return \Imagick |
||
225 | * @throws \ImagickException |
||
226 | */ |
||
227 | private function newImage(int $width, int $height): \Imagick |
||
235 | |||
236 | /** |
||
237 | * @param Image $watermark |
||
238 | * @param int $x |
||
239 | * @param int $y |
||
240 | * @return ImageInterface |
||
241 | * @throws \Exception |
||
242 | */ |
||
243 | protected function prepareWatermark(Image $watermark, int $x, int $y): ImageInterface |
||
250 | } |
||
251 |