1 | <?php declare(strict_types=1); |
||||
2 | |||||
3 | namespace Compolomus\Compomage; |
||||
4 | |||||
5 | use Compolomus\Compomage\Interfaces\ImageInterface; |
||||
6 | use Exception; |
||||
7 | use InvalidArgumentException; |
||||
8 | use LogicException; |
||||
9 | use RangeException; |
||||
10 | use SplFileObject; |
||||
11 | |||||
12 | class GD extends AbstractImage |
||||
13 | { |
||||
14 | /** |
||||
15 | * GD constructor. |
||||
16 | * @param string $image |
||||
17 | * @throws Exception |
||||
18 | */ |
||||
19 | 14 | public function __construct(string $image) |
|||
20 | { |
||||
21 | 14 | $this->init($image); |
|||
22 | } |
||||
23 | |||||
24 | /** |
||||
25 | * @param int $width |
||||
26 | * @param int $height |
||||
27 | * @return ImageInterface |
||||
28 | * @throws Exception |
||||
29 | */ |
||||
30 | public function resizeByTransparentBackground(int $width, int $height): ImageInterface |
||||
31 | { |
||||
32 | $temp = new SplFileObject(tempnam(sys_get_temp_dir(), 'image' . mt_rand()), 'w+'); |
||||
33 | imagepng($this->newImage($width, $height), $temp->getRealPath(), 9, PNG_ALL_FILTERS); |
||||
34 | |||||
35 | return $this->setBackground($width, $height, new Image($temp->getRealPath(), Image::GD)); |
||||
36 | } |
||||
37 | |||||
38 | /** |
||||
39 | * @param int $width |
||||
40 | * @param int $height |
||||
41 | * @return ImageInterface |
||||
42 | * @throws Exception |
||||
43 | */ |
||||
44 | public function resizeByBlurBackground(int $width, int $height): ImageInterface |
||||
45 | { |
||||
46 | $background = new Image(base64_encode((string) $this), Image::GD); |
||||
47 | $background->blur()->resize($width, $height); |
||||
48 | |||||
49 | return $this->setBackground($width, $height, $background); |
||||
50 | } |
||||
51 | |||||
52 | /** |
||||
53 | * @param int $level |
||||
54 | * @return ImageInterface |
||||
55 | */ |
||||
56 | public function brightness(int $level): ImageInterface |
||||
57 | { |
||||
58 | if (!$this->compareRangeValue($level, 255)) |
||||
59 | { |
||||
60 | throw new InvalidArgumentException('Wrong brightness level, range -255 - 255, ' . $level . ' given'); |
||||
61 | } |
||||
62 | imagefilter($this->getImage(), IMG_FILTER_BRIGHTNESS, $level); |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
63 | |||||
64 | return $this; |
||||
65 | } |
||||
66 | |||||
67 | /** |
||||
68 | * @param int $level |
||||
69 | * @return ImageInterface |
||||
70 | */ |
||||
71 | public function contrast(int $level): ImageInterface |
||||
72 | { |
||||
73 | if (!$this->compareRangeValue($level, 100)) |
||||
74 | { |
||||
75 | throw new InvalidArgumentException('Wrong contrast level, range -100 - 100, ' . $level . ' given'); |
||||
76 | } |
||||
77 | imagefilter($this->getImage(), IMG_FILTER_CONTRAST, $level); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagefilter() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
78 | |||||
79 | return $this; |
||||
80 | } |
||||
81 | |||||
82 | /** |
||||
83 | * @return ImageInterface |
||||
84 | */ |
||||
85 | public function negate(): ImageInterface |
||||
86 | { |
||||
87 | imagefilter($this->getImage(), IMG_FILTER_NEGATE); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagefilter() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
88 | |||||
89 | return $this; |
||||
90 | } |
||||
91 | |||||
92 | /** |
||||
93 | * @return ImageInterface |
||||
94 | */ |
||||
95 | public function blur(): ImageInterface |
||||
96 | { |
||||
97 | for ($i = 0; $i < 30; $i++) { |
||||
98 | if ($i % 5 === 0) { |
||||
99 | imagefilter($this->getImage(), IMG_FILTER_SMOOTH, -7); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagefilter() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
100 | } |
||||
101 | imagefilter($this->getImage(), IMG_FILTER_GAUSSIAN_BLUR); |
||||
102 | } |
||||
103 | |||||
104 | return $this; |
||||
105 | } |
||||
106 | |||||
107 | /** |
||||
108 | * @return ImageInterface |
||||
109 | */ |
||||
110 | public function flip(): ImageInterface |
||||
111 | { |
||||
112 | imageflip($this->getImage(), IMG_FLIP_VERTICAL); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imageflip() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
113 | |||||
114 | return $this; |
||||
115 | } |
||||
116 | |||||
117 | /** |
||||
118 | * @return ImageInterface |
||||
119 | */ |
||||
120 | public function flop(): ImageInterface |
||||
121 | { |
||||
122 | imageflip($this->getImage(), IMG_FLIP_HORIZONTAL); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imageflip() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
123 | |||||
124 | return $this; |
||||
125 | } |
||||
126 | |||||
127 | /** |
||||
128 | * @return ImageInterface |
||||
129 | */ |
||||
130 | public function grayscale(): ImageInterface |
||||
131 | { |
||||
132 | imagefilter($this->getImage(), IMG_FILTER_GRAYSCALE); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagefilter() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
133 | |||||
134 | return $this; |
||||
135 | } |
||||
136 | |||||
137 | /** |
||||
138 | * @param string $text |
||||
139 | * @param string $font |
||||
140 | * @param string $position |
||||
141 | * @return $this |
||||
142 | * @throws InvalidArgumentException |
||||
143 | * @throws Exception |
||||
144 | */ |
||||
145 | 1 | public function copyright(string $text, string $font, string $position = 'SouthWest'): ImageInterface |
|||
146 | { |
||||
147 | 1 | if (!array_key_exists(strtoupper($position), self::POSITIONS)) { |
|||
148 | 1 | throw new InvalidArgumentException('Wrong position'); |
|||
149 | } |
||||
150 | |||||
151 | imagecopymerge( |
||||
152 | $this->getImage(), |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $dst_im of imagecopymerge() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
153 | $image = $this->prepareImage($text, $font), |
||||
154 | (int) ((($this->getWidth() - imagesx($image)) / 2) * self::POSITIONS[strtoupper($position)]['x']) + self::POSITIONS[strtoupper($position)]['padX'], |
||||
155 | (int) ((($this->getHeight() - imagesy($image)) / 2) * self::POSITIONS[strtoupper($position)]['y']) + self::POSITIONS[strtoupper($position)]['padY'], |
||||
156 | 0, |
||||
157 | 0, |
||||
158 | $this->getWidth(), |
||||
159 | $this->getHeight(), |
||||
160 | 80 |
||||
161 | ); |
||||
162 | |||||
163 | return $this; |
||||
164 | } |
||||
165 | |||||
166 | /** |
||||
167 | * @param string $text |
||||
168 | * @param string $font |
||||
169 | * @return resource |
||||
170 | * @throws InvalidArgumentException |
||||
171 | * @throws Exception |
||||
172 | */ |
||||
173 | private function prepareImage(string $text, string $font) |
||||
174 | { |
||||
175 | if (!$coordinates = imagettfbbox($fontSize = 15, 0, $font, $text)) { |
||||
176 | throw new InvalidArgumentException('Does not support font'); |
||||
177 | } |
||||
178 | |||||
179 | $minX = min([$coordinates[0], $coordinates[2], $coordinates[4], $coordinates[6]]); |
||||
180 | $maxX = max([$coordinates[0], $coordinates[2], $coordinates[4], $coordinates[6]]); |
||||
181 | $minY = min([$coordinates[1], $coordinates[3], $coordinates[5], $coordinates[7]]); |
||||
182 | $maxY = max([$coordinates[1], $coordinates[3], $coordinates[5], $coordinates[7]]); |
||||
183 | $textX = (int) abs($minX) + 1; |
||||
184 | $textY = (int) abs($minY) + 1; |
||||
185 | $image = $this->newImage($maxX - $minX + 2, $maxY - $minY + 2); |
||||
186 | imagecolortransparent($image, $white = imagecolorallocate($image, 0, 0, 0)); |
||||
187 | imagefilledrectangle($image, 0, 0, $this->getWidth(), 20, $white); |
||||
188 | imagettftext($image, $fontSize, 0, $textX, $textY, $white, $font, $text); |
||||
189 | imagettftext($image, $fontSize, 0, $textX + 1, $textY + 1, $blue = imagecolorallocate($image, 0, 128, 128), |
||||
190 | $font, $text); |
||||
191 | imagettftext($image, $fontSize, 0, $textX + 1, $textY + 1, $red = imagecolorallocate($image, 255, 0, 0), $font, |
||||
192 | $text); |
||||
193 | imagettftext($image, $fontSize, 0, $textX + 2, $textY + 2, $black = imagecolorallocate($image, 255, 255, 255), |
||||
194 | $font, $text); |
||||
195 | imagettftext($image, $fontSize, 0, $textX + 2, $textY + 2, $gray = imagecolorallocate($image, 128, 128, 128), |
||||
196 | $font, $text); |
||||
197 | |||||
198 | return $image; |
||||
199 | } |
||||
200 | |||||
201 | /** |
||||
202 | * @param int $width |
||||
203 | * @param int $height |
||||
204 | * @return resource |
||||
205 | */ |
||||
206 | 3 | protected function newImage(int $width, int $height) |
|||
207 | { |
||||
208 | 3 | $newimage = imagecreatetruecolor($width, $height); |
|||
209 | 3 | $transparent = imagecolorallocatealpha($newimage, 255, 255, 255, 127); |
|||
210 | 3 | imagefill($newimage, 0, 0, $transparent); |
|||
211 | 3 | imagealphablending($newimage, true); |
|||
212 | 3 | imagesavealpha($newimage, true); |
|||
213 | |||||
214 | 3 | return $newimage; |
|||
0 ignored issues
–
show
|
|||||
215 | } |
||||
216 | |||||
217 | /** |
||||
218 | * @param int $width |
||||
219 | * @param int $height |
||||
220 | * @return ImageInterface |
||||
221 | */ |
||||
222 | 2 | public function resize(int $width, int $height): ImageInterface |
|||
223 | { |
||||
224 | 2 | $newimage = $this->newImage($width, $height); |
|||
225 | 2 | imagecopyresampled($newimage, $this->getImage(), 0, 0, 0, 0, $width, $height, $this->getWidth(), |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $src_image of imagecopyresampled() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
226 | 2 | $this->getHeight()); |
|||
227 | 2 | $this->setImage($newimage); |
|||
228 | 2 | $this->setSizes(); |
|||
229 | |||||
230 | 2 | return $this; |
|||
231 | } |
||||
232 | |||||
233 | 12 | protected function setSizes(): void |
|||
234 | { |
||||
235 | 12 | $this->setWidth(imagesx($this->getImage())); |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagesx() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
236 | 12 | $this->setHeight(imagesy($this->getImage())); |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagesy() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
237 | 12 | $this->setOrientation(); |
|||
238 | } |
||||
239 | |||||
240 | /** |
||||
241 | * @param int $width |
||||
242 | * @param int $height |
||||
243 | * @param int $x |
||||
244 | * @param int $y |
||||
245 | * @return ImageInterface |
||||
246 | */ |
||||
247 | public function crop(int $width, int $height, int $x, int $y): ImageInterface |
||||
248 | { |
||||
249 | $width -= $x; |
||||
250 | $height -= $y; |
||||
251 | $newimage = $this->newImage($width, $height); |
||||
252 | imagecopyresampled($newimage, $this->getImage(), 0, 0, $x, $y, $width, $height, $width, $height); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $src_image of imagecopyresampled() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
253 | $this->setImage($newimage); |
||||
254 | $this->setSizes(); |
||||
255 | |||||
256 | return $this; |
||||
257 | } |
||||
258 | |||||
259 | /** |
||||
260 | * @param int $angle |
||||
261 | * @return ImageInterface |
||||
262 | */ |
||||
263 | 1 | public function rotate(int $angle = 90): ImageInterface |
|||
264 | { |
||||
265 | 1 | $angle *= -1; |
|||
266 | 1 | $transparent = imagecolorallocatealpha($this->image, 0, 0, 0, 127); |
|||
267 | 1 | $rotate = imagerotate($this->getImage(), $angle, $transparent); |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagerotate() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
268 | 1 | imagealphablending($rotate, true); |
|||
269 | 1 | imagesavealpha($rotate, true); |
|||
270 | 1 | $this->setImage($rotate); |
|||
271 | 1 | $this->setSizes(); |
|||
272 | |||||
273 | 1 | return $this; |
|||
274 | } |
||||
275 | |||||
276 | /** |
||||
277 | * @throws LogicException |
||||
278 | * @throws RangeException |
||||
279 | * @return string |
||||
280 | */ |
||||
281 | public function __toString(): string |
||||
282 | { |
||||
283 | $temp = new SplFileObject(tempnam(sys_get_temp_dir(), 'image' . mt_rand()), 'w+'); |
||||
284 | imagepng($this->getImage(), $temp->getRealPath(), 9, PNG_ALL_FILTERS); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagepng() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
285 | |||||
286 | return trim(file_get_contents($temp->getRealPath())); |
||||
287 | } |
||||
288 | |||||
289 | /** |
||||
290 | * @param string $filename |
||||
291 | * @param int $quality |
||||
292 | * @return bool |
||||
293 | */ |
||||
294 | 1 | public function save(string $filename, $quality = 100): bool |
|||
295 | { |
||||
296 | 1 | return imagepng($this->getImage(), $filename . '.png', (int) ($quality / 11), PNG_ALL_FILTERS); |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagepng() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
297 | } |
||||
298 | |||||
299 | /** |
||||
300 | * @param int $width |
||||
301 | * @param int $height |
||||
302 | * @param int $newWidth |
||||
303 | * @param int $newHeight |
||||
304 | * @return ImageInterface |
||||
305 | */ |
||||
306 | 1 | protected function prepareThumbnail( |
|||
307 | int $width, |
||||
308 | int $height, |
||||
309 | int $newWidth = 0, |
||||
310 | int $newHeight = 0 |
||||
311 | ): ImageInterface { |
||||
312 | 1 | imagecopyresampled( |
|||
313 | 1 | $newimage = $this->newImage($width, $height), |
|||
314 | 1 | $this->getImage(), |
|||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $src_image of imagecopyresampled() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
315 | 1 | 0 - (int) (($newWidth - $width) / 2), |
|||
316 | 1 | 0 - (int) (($newHeight - $height) / 2), |
|||
317 | 0, |
||||
318 | 0, |
||||
319 | $newWidth, |
||||
320 | $newHeight, |
||||
321 | 1 | $this->getWidth(), |
|||
322 | 1 | $this->getHeight() |
|||
323 | ); |
||||
324 | 1 | $this->setImage($newimage); |
|||
325 | 1 | $this->setSizes(); |
|||
326 | |||||
327 | 1 | return $this; |
|||
328 | } |
||||
329 | |||||
330 | /** |
||||
331 | * @param string $source |
||||
332 | * @return ImageInterface |
||||
333 | * @throws InvalidArgumentException |
||||
334 | * @throws Exception |
||||
335 | */ |
||||
336 | 13 | protected function tmp(string $source): ImageInterface |
|||
337 | { |
||||
338 | 13 | if (!$image = @imagecreatefromstring($source)) { |
|||
339 | 1 | throw new InvalidArgumentException('Image create failed'); |
|||
340 | } |
||||
341 | 12 | $this->setImage($image); |
|||
342 | 12 | $this->setSizes(); |
|||
343 | // save transparent |
||||
344 | 12 | imagesavealpha($this->getImage(), true); |
|||
345 | 12 | imagealphablending($this->getImage(), false); |
|||
346 | |||||
347 | 12 | return $this; |
|||
348 | } |
||||
349 | |||||
350 | /** |
||||
351 | * @param ImageInterface $watermark |
||||
352 | * @param int $x |
||||
353 | * @param int $y |
||||
354 | * @return ImageInterface |
||||
355 | */ |
||||
356 | protected function prepareWatermark($watermark, int $x, int $y): ImageInterface |
||||
357 | { |
||||
358 | imagealphablending($this->getImage(), true); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagealphablending() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
359 | imagesavealpha($this->getImage(), true); |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $image of imagesavealpha() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
360 | imagecopyresampled( |
||||
361 | $this->getImage(), |
||||
0 ignored issues
–
show
It seems like
$this->getImage() can also be of type Imagick ; however, parameter $dst_image of imagecopyresampled() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
362 | $watermark->getImage(), |
||||
0 ignored issues
–
show
It seems like
$watermark->getImage() can also be of type Imagick ; however, parameter $src_image of imagecopyresampled() does only seem to accept GdImage|resource , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
363 | $x, |
||||
364 | $y, |
||||
365 | 0, |
||||
366 | 0, |
||||
367 | $width = $watermark->getWidth(), |
||||
0 ignored issues
–
show
The method
getWidth() does not exist on Compolomus\Compomage\Interfaces\ImageInterface . Since it exists in all sub-types, consider adding an abstract or default implementation to Compolomus\Compomage\Interfaces\ImageInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
368 | $height = $watermark->getHeight(), |
||||
0 ignored issues
–
show
The method
getHeight() does not exist on Compolomus\Compomage\Interfaces\ImageInterface . Since it exists in all sub-types, consider adding an abstract or default implementation to Compolomus\Compomage\Interfaces\ImageInterface .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
369 | $width, |
||||
370 | $height |
||||
371 | ); |
||||
372 | |||||
373 | return $this; |
||||
374 | } |
||||
375 | } |
||||
376 |