Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
92.36% |
266 / 288 |
|
75.86% |
22 / 29 |
CRAP | |
0.00% |
0 / 1 |
Gd | |
92.36% |
266 / 288 |
|
75.86% |
22 / 29 |
138.65 | |
0.00% |
0 / 1 |
createResource | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
load | |
89.47% |
17 / 19 |
|
0.00% |
0 / 1 |
10.12 | |||
loadFromString | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
6.03 | |||
create | |
89.47% |
17 / 19 |
|
0.00% |
0 / 1 |
10.12 | |||
createIndex | |
80.00% |
12 / 15 |
|
0.00% |
0 / 1 |
8.51 | |||
resizeToWidth | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
resizeToHeight | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
resize | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
scale | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
crop | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
cropThumb | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
8 | |||
rotate | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
flip | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
flop | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
adjust | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
draw | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
effect | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
filter | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
layer | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
type | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
convert | |
100.00% |
29 / 29 |
|
100.00% |
1 / 1 |
13 | |||
writeToFile | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
6 | |||
outputToHttp | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
6 | |||
destroy | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
6.10 | |||
createColor | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
6 | |||
__toString | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
copyImage | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
2.01 | |||
parseImage | |
63.64% |
21 / 33 |
|
0.00% |
0 / 1 |
23.42 | |||
generateImage | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Image\Adapter; |
15 | |
16 | use Pop\Image\Adjust; |
17 | use Pop\Image\Color; |
18 | use Pop\Image\Draw; |
19 | use Pop\Image\Effect; |
20 | use Pop\Image\Filter; |
21 | use Pop\Image\Layer; |
22 | use Pop\Image\Type; |
23 | |
24 | /** |
25 | * Gd adapter class |
26 | * |
27 | * @category Pop |
28 | * @package Pop\Image |
29 | * @author Nick Sagona, III <dev@nolainteractive.com> |
30 | * @copyright Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
31 | * @license http://www.popphp.org/license New BSD License |
32 | * @version 3.4.0 |
33 | */ |
34 | class Gd extends AbstractAdapter |
35 | { |
36 | |
37 | /** |
38 | * Create the image resource |
39 | * |
40 | * @return void |
41 | */ |
42 | public function createResource() |
43 | { |
44 | $this->resource = null; |
45 | } |
46 | |
47 | /** |
48 | * Load the image resource from the existing image file |
49 | * |
50 | * @param string $name |
51 | * @throws Exception |
52 | * @return Gd |
53 | */ |
54 | public function load($name = null) |
55 | { |
56 | if (null !== $name) { |
57 | $this->name = $name; |
58 | } |
59 | |
60 | if ((null === $this->name) || !file_exists($this->name)) { |
61 | throw new Exception('Error: The image file has not been passed to the image adapter'); |
62 | } |
63 | |
64 | if (stripos($this->name, '.gif') !== false) { |
65 | $this->resource = imagecreatefromgif($this->name); |
66 | } else if (stripos($this->name, '.jp') !== false) { |
67 | $this->resource = imagecreatefromjpeg($this->name); |
68 | if (function_exists('exif_read_data')) { |
69 | $exif = @exif_read_data($this->name); |
70 | if ($exif !== false) { |
71 | $this->exif = $exif; |
72 | } |
73 | } |
74 | } else if (stripos($this->name, '.png') !== false) { |
75 | $this->resource = imagecreatefrompng($this->name); |
76 | } else { |
77 | throw new Exception('Error: The image file must be a GIF, PNG or JPG'); |
78 | } |
79 | |
80 | if ($this->resource === false) { |
81 | throw new Exception('Error: Unable to load image resource'); |
82 | } |
83 | |
84 | $this->parseImage(getimagesize($this->name), file_get_contents($this->name)); |
85 | return $this; |
86 | } |
87 | |
88 | /** |
89 | * Load the image resource from data |
90 | * |
91 | * @param string $data |
92 | * @param string $name |
93 | * @throws Exception |
94 | * @return Gd |
95 | */ |
96 | public function loadFromString($data, $name = null) |
97 | { |
98 | if (null !== $name) { |
99 | $this->name = $name; |
100 | } |
101 | |
102 | $this->resource = @imagecreatefromstring($data); |
103 | |
104 | if ($this->resource === false) { |
105 | throw new Exception('Error: Unable to load image resource'); |
106 | } |
107 | |
108 | $this->parseImage(getimagesizefromstring($data), $data); |
109 | |
110 | if ((strpos($this->format, 'jp') !== false) && function_exists('exif_read_data')) { |
111 | $exif = @exif_read_data('data://image/jpeg;base64,' . base64_encode($data)); |
112 | if ($exif !== false) { |
113 | $this->exif = $exif; |
114 | } |
115 | } |
116 | |
117 | return $this; |
118 | } |
119 | |
120 | /** |
121 | * Create a new image resource |
122 | * |
123 | * @param int $width |
124 | * @param int $height |
125 | * @param string $name |
126 | * @throws Exception |
127 | * @return Gd |
128 | */ |
129 | public function create($width = null, $height = null, $name = null) |
130 | { |
131 | if ((null !== $width) && (null !== $height)) { |
132 | $this->width = $width; |
133 | $this->height = $height; |
134 | } |
135 | |
136 | if (null !== $name) { |
137 | $this->name = $name; |
138 | } |
139 | |
140 | if ((null === $this->width) && (null === $this->height)) { |
141 | throw new Exception('Error: You must pass a width and a height'); |
142 | } |
143 | |
144 | if (stripos($this->name, '.gif') !== false) { |
145 | $this->resource = imagecreate($this->width, $this->height); |
146 | $this->indexed = true; |
147 | $this->format = 'gif'; |
148 | } else { |
149 | $this->resource = imagecreatetruecolor($this->width, $this->height); |
150 | if (stripos($this->name, '.png') !== false) { |
151 | $this->format = 'png'; |
152 | } else if (stripos($this->name, '.jp') !== false) { |
153 | $this->format = 'jpg'; |
154 | } |
155 | } |
156 | |
157 | if ($this->resource === false) { |
158 | throw new Exception('Error: Unable to create image resource'); |
159 | } |
160 | |
161 | return $this; |
162 | } |
163 | |
164 | /** |
165 | * Create a new image resource |
166 | * |
167 | * @param int $width |
168 | * @param int $height |
169 | * @param string $name |
170 | * @throws Exception |
171 | * @return Gd |
172 | */ |
173 | public function createIndex($width = null, $height = null, $name = null) |
174 | { |
175 | if ((null !== $width) && (null !== $height)) { |
176 | $this->width = $width; |
177 | $this->height = $height; |
178 | } |
179 | |
180 | if (null !== $name) { |
181 | $this->name = $name; |
182 | } |
183 | |
184 | if ((null === $this->width) && (null === $this->height)) { |
185 | throw new Exception('Error: You must pass a width and a height'); |
186 | } |
187 | |
188 | $this->resource = imagecreate($this->width, $this->height); |
189 | $this->indexed = true; |
190 | |
191 | if (stripos($this->name, '.png') !== false) { |
192 | $this->format = 'png'; |
193 | } else { |
194 | $this->format = 'gif'; |
195 | } |
196 | |
197 | if ($this->resource === false) { |
198 | throw new Exception('Error: Unable to create image resource'); |
199 | } |
200 | |
201 | return $this; |
202 | } |
203 | |
204 | /** |
205 | * Resize the image object to the width parameter passed |
206 | * |
207 | * @param int $w |
208 | * @return Gd |
209 | */ |
210 | public function resizeToWidth($w) |
211 | { |
212 | $scale = $w / $this->width; |
213 | $h = round($this->height * $scale); |
214 | $this->copyImage($w, $h); |
215 | |
216 | return $this; |
217 | } |
218 | |
219 | /** |
220 | * Resize the image object to the height parameter passed |
221 | * |
222 | * @param int $h |
223 | * @return Gd |
224 | */ |
225 | public function resizeToHeight($h) |
226 | { |
227 | $scale = $h / $this->height; |
228 | $w = round($this->width * $scale); |
229 | $this->copyImage($w, $h); |
230 | |
231 | return $this; |
232 | } |
233 | |
234 | /** |
235 | * Resize the image object, allowing for the largest dimension |
236 | * to be scaled to the value of the $px argument. |
237 | * |
238 | * @param int $px |
239 | * @return Gd |
240 | */ |
241 | public function resize($px) |
242 | { |
243 | $scale = ($this->width > $this->height) ? ($px / $this->width) : ($px / $this->height); |
244 | $w = round($this->width * $scale); |
245 | $h = round($this->height * $scale); |
246 | $this->copyImage($w, $h); |
247 | |
248 | return $this; |
249 | } |
250 | |
251 | /** |
252 | * Scale the image object, allowing for the dimensions to be scaled |
253 | * proportionally to the value of the $scale argument. |
254 | * |
255 | * @param float $scale |
256 | * @return Gd |
257 | */ |
258 | public function scale($scale) |
259 | { |
260 | $w = round($this->width * $scale); |
261 | $h = round($this->height * $scale); |
262 | $this->copyImage($w, $h); |
263 | |
264 | return $this; |
265 | } |
266 | |
267 | /** |
268 | * Crop the image object to a image whose dimensions are based on the |
269 | * value of the $wid and $hgt argument. The optional $x and $y arguments |
270 | * allow for the adjustment of the crop to select a certain area of the |
271 | * image to be cropped. |
272 | * |
273 | * @param int $w |
274 | * @param int $h |
275 | * @param int $x |
276 | * @param int $y |
277 | * @return Gd |
278 | */ |
279 | public function crop($w, $h, $x = 0, $y = 0) |
280 | { |
281 | $result = imagecreatetruecolor($w, $h); |
282 | imagecopyresampled( |
283 | $result, $this->resource, 0, 0, $x, $y, $this->width, $this->height, $this->width, $this->height |
284 | ); |
285 | |
286 | if ($this->indexed) { |
287 | imagetruecolortopalette($result, false, 255); |
288 | } |
289 | |
290 | $this->resource = $result; |
291 | $this->width = imagesx($this->resource); |
292 | $this->height = imagesy($this->resource); |
293 | |
294 | return $this; |
295 | } |
296 | |
297 | /** |
298 | * Crop the image object to a square image whose dimensions are based on the |
299 | * value of the $px argument. The optional $offset argument allows for the |
300 | * adjustment of the crop to select a certain area of the image to be cropped. |
301 | * |
302 | * @param int $px |
303 | * @param int $offset |
304 | * @return Gd |
305 | */ |
306 | public function cropThumb($px, $offset = null) |
307 | { |
308 | $xOffset = 0; |
309 | $yOffset = 0; |
310 | $scale = ($this->width > $this->height) ? ($px / $this->height) : ($px / $this->width); |
311 | $w = round($this->width * $scale); |
312 | $h = round($this->height * $scale); |
313 | |
314 | if (null !== $offset) { |
315 | if ($this->width > $this->height) { |
316 | $xOffset = $offset; |
317 | $yOffset = 0; |
318 | } else if ($this->width < $this->height) { |
319 | $xOffset = 0; |
320 | $yOffset = $offset; |
321 | } |
322 | } else { |
323 | if ($this->width > $this->height) { |
324 | $xOffset = round(($this->width - $this->height) / 2); |
325 | $yOffset = 0; |
326 | } else if ($this->width < $this->height) { |
327 | $xOffset = 0; |
328 | $yOffset = round(($this->height - $this->width) / 2); |
329 | } |
330 | } |
331 | |
332 | $result = imagecreatetruecolor($px, $px); |
333 | imagecopyresampled($result, $this->resource, 0, 0, $xOffset, $yOffset, $w, $h, $this->width, $this->height); |
334 | |
335 | if ($this->indexed) { |
336 | imagetruecolortopalette($result, false, 255); |
337 | } |
338 | |
339 | $this->resource = $result; |
340 | $this->width = imagesx($this->resource); |
341 | $this->height = imagesy($this->resource); |
342 | |
343 | return $this; |
344 | } |
345 | |
346 | /** |
347 | * Rotate the image object |
348 | * |
349 | * @param int $degrees |
350 | * @param Color\ColorInterface $bgColor |
351 | * @param int $alpha |
352 | * @return Gd |
353 | */ |
354 | public function rotate($degrees, Color\ColorInterface $bgColor = null, $alpha = null) |
355 | { |
356 | $this->resource = imagerotate($this->resource, $degrees, $this->createColor($bgColor, $alpha)); |
357 | $this->width = imagesx($this->resource); |
358 | $this->height = imagesy($this->resource); |
359 | return $this; |
360 | } |
361 | |
362 | /** |
363 | * Method to flip the image over the x-axis |
364 | * |
365 | * @return Gd |
366 | */ |
367 | public function flip() |
368 | { |
369 | $curWidth = $this->width; |
370 | $curHeight = $this->height; |
371 | $srcX = 0; |
372 | $srcY = $this->height - 1; // Compensate for a 1-pixel space on the flipped image |
373 | $this->height = 0 - $this->height; |
374 | |
375 | $this->copyImage($curWidth, $curHeight, $srcX , $srcY); |
376 | $this->height = abs($this->height); |
377 | |
378 | return $this; |
379 | } |
380 | |
381 | /** |
382 | * Method to flip the image over the y-axis |
383 | * |
384 | * @return Gd |
385 | */ |
386 | public function flop() |
387 | { |
388 | $curWidth = $this->width; |
389 | $curHeight = $this->height; |
390 | $srcX = $this->width - 1; // Compensate for a 1-pixel space on the flipped image |
391 | $srcY = 0; |
392 | $this->width = 0 - $this->width; |
393 | |
394 | $this->copyImage($curWidth, $curHeight, $srcX , $srcY); |
395 | $this->width = abs($this->width); |
396 | |
397 | return $this; |
398 | } |
399 | |
400 | /** |
401 | * Get the image adjust object |
402 | * |
403 | * @return Adjust\AdjustInterface |
404 | */ |
405 | public function adjust() |
406 | { |
407 | if (null === $this->adjust) { |
408 | $this->adjust = new Adjust\Gd($this); |
409 | } |
410 | if (null === $this->adjust->getImage()) { |
411 | $this->adjust->setImage($this); |
412 | } |
413 | |
414 | return $this->adjust; |
415 | } |
416 | |
417 | /** |
418 | * Get the image draw object |
419 | * |
420 | * @return Draw\DrawInterface |
421 | */ |
422 | public function draw() |
423 | { |
424 | if (null === $this->draw) { |
425 | $this->draw = new Draw\Gd($this); |
426 | } |
427 | if (null === $this->draw->getImage()) { |
428 | $this->draw->setImage($this); |
429 | } |
430 | return $this->draw; |
431 | } |
432 | |
433 | /** |
434 | * Get the image effect object |
435 | * |
436 | * @return Effect\EffectInterface |
437 | */ |
438 | public function effect() |
439 | { |
440 | if (null === $this->effect) { |
441 | $this->effect = new Effect\Gd($this); |
442 | } |
443 | if (null === $this->effect->getImage()) { |
444 | $this->effect->setImage($this); |
445 | } |
446 | return $this->effect; |
447 | } |
448 | |
449 | /** |
450 | * Get the image filter object |
451 | * |
452 | * @return Filter\FilterInterface |
453 | */ |
454 | public function filter() |
455 | { |
456 | if (null === $this->filter) { |
457 | $this->filter = new Filter\Gd($this); |
458 | } |
459 | if (null === $this->filter->getImage()) { |
460 | $this->filter->setImage($this); |
461 | } |
462 | return $this->filter; |
463 | } |
464 | |
465 | /** |
466 | * Get the image layer object |
467 | * |
468 | * @return Layer\LayerInterface |
469 | */ |
470 | public function layer() |
471 | { |
472 | if (null === $this->layer) { |
473 | $this->layer = new Layer\Gd($this); |
474 | } |
475 | if (null === $this->layer->getImage()) { |
476 | $this->layer->setImage($this); |
477 | } |
478 | return $this->layer; |
479 | } |
480 | |
481 | /** |
482 | * Get the image type object |
483 | * |
484 | * @return Type\TypeInterface |
485 | */ |
486 | public function type() |
487 | { |
488 | if (null === $this->type) { |
489 | $this->type = new Type\Gd($this); |
490 | } |
491 | if (null === $this->type->getImage()) { |
492 | $this->type->setImage($this); |
493 | } |
494 | return $this->type; |
495 | } |
496 | |
497 | /** |
498 | * Convert the image object to another format |
499 | * |
500 | * @param string $to |
501 | * @throws Exception |
502 | * @return Gd |
503 | */ |
504 | public function convert($to) |
505 | { |
506 | $to = strtolower($to); |
507 | |
508 | if (($to != 'jpg') && ($to != 'jpeg') && ($to != 'gif') && ($to != 'png')) { |
509 | throw new Exception('Error: The image type must be a GIF, PNG or JPG'); |
510 | } |
511 | |
512 | if (null === $this->resource) { |
513 | throw new Exception('Error: An image resource has not been created or loaded'); |
514 | } |
515 | |
516 | switch ($to) { |
517 | case 'jpg': |
518 | case 'jpeg': |
519 | $this->format = 'jpg'; |
520 | $this->indexed = false; |
521 | break; |
522 | case 'png': |
523 | $this->format = 'png'; |
524 | break; |
525 | case 'gif': |
526 | $this->format = 'gif'; |
527 | $this->indexed = true; |
528 | break; |
529 | } |
530 | |
531 | if ((null !== $this->name) && (strpos($this->name, '.') !== false)) { |
532 | $this->name = substr($this->name, 0, (strrpos($this->name, '.') + 1)) . $this->format; |
533 | } |
534 | |
535 | $result = imagecreatetruecolor($this->width, $this->height); |
536 | imagecopyresampled( |
537 | $result, $this->resource, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height |
538 | ); |
539 | |
540 | if ($this->indexed) { |
541 | imagetruecolortopalette($result, false, 255); |
542 | } |
543 | |
544 | $this->resource = $result; |
545 | $this->width = imagesx($this->resource); |
546 | $this->height = imagesy($this->resource); |
547 | |
548 | return $this; |
549 | } |
550 | |
551 | /** |
552 | * Write the image object to a file on disk |
553 | * |
554 | * @param string $to |
555 | * @param int $quality |
556 | * @throws Exception |
557 | * @return void |
558 | */ |
559 | public function writeToFile($to = null, $quality = 100) |
560 | { |
561 | if (null === $this->resource) { |
562 | throw new Exception('Error: An image resource has not been created or loaded'); |
563 | } |
564 | |
565 | if (((int)$quality < 0) || ((int)$quality > 100)) { |
566 | throw new \OutOfRangeException('Error: The quality parameter must be between 0 and 100'); |
567 | } |
568 | |
569 | $this->format = strtolower($this->format); |
570 | |
571 | if (null === $to) { |
572 | $to = (null !== $this->name) ? basename($this->name) : 'pop-image.' . $this->format; |
573 | } else { |
574 | $this->name = $to; |
575 | } |
576 | |
577 | $this->generateImage((int)$quality, $to); |
578 | } |
579 | |
580 | /** |
581 | * Output the image object directly to HTTP |
582 | * |
583 | * @param int $quality |
584 | * @param string $to |
585 | * @param boolean $download |
586 | * @param boolean $sendHeaders |
587 | * @param array $headers |
588 | * @throws Exception |
589 | * @return void |
590 | */ |
591 | public function outputToHttp($quality = 100, $to = null, $download = false, $sendHeaders = true, array $headers = []) |
592 | { |
593 | if (null === $this->resource) { |
594 | throw new Exception('Error: An image resource has not been created or loaded'); |
595 | } |
596 | |
597 | if (((int)$quality < 0) || ((int)$quality > 100)) { |
598 | throw new \OutOfRangeException('Error: The quality parameter must be between 0 and 100'); |
599 | } |
600 | |
601 | $this->format = strtolower($this->format); |
602 | |
603 | if (null === $to) { |
604 | $to = (null !== $this->name) ? basename($this->name) : 'pop-image.' . $this->format; |
605 | } |
606 | |
607 | $this->sendHeaders($to, $download, $headers); |
608 | $this->generateImage((int)$quality); |
609 | } |
610 | |
611 | /** |
612 | * Destroy the image object and the related image file directly |
613 | * |
614 | * @param boolean $delete |
615 | * @return void |
616 | */ |
617 | public function destroy($delete = false) |
618 | { |
619 | // Destroy the image resource. |
620 | if (null !== $this->resource) { |
621 | if (!is_string($this->resource) && is_resource($this->resource)) { |
622 | imagedestroy($this->resource); |
623 | } |
624 | } |
625 | |
626 | $this->resource = null; |
627 | clearstatcache(); |
628 | |
629 | // If the $delete flag is passed, delete the image file. |
630 | if (($delete) && file_exists($this->name)) { |
631 | unlink($this->name); |
632 | } |
633 | } |
634 | |
635 | /** |
636 | * Create and return a color |
637 | * |
638 | * @param Color\ColorInterface $color |
639 | * @param int $alpha |
640 | * @throws Exception |
641 | * @return mixed |
642 | */ |
643 | public function createColor(Color\ColorInterface $color = null, $alpha = null) |
644 | { |
645 | if (null === $color) { |
646 | $color = new Color\Rgb(0, 0, 0); |
647 | } |
648 | |
649 | if (!($color instanceof Color\Rgb)) { |
650 | $color = $color->toRgb(); |
651 | } |
652 | |
653 | $r = $color->getR(); |
654 | $g = $color->getG(); |
655 | $b = $color->getB(); |
656 | |
657 | if (null !== $alpha) { |
658 | if (((int)$alpha < 0) || ((int)$alpha > 127)) { |
659 | throw new \OutOfRangeException('Error: The alpha parameter must be between 0 and 127'); |
660 | } |
661 | return imagecolorallocatealpha($this->resource, (int)$r, (int)$g, (int)$b, (int)$alpha); |
662 | } else { |
663 | return imagecolorallocate($this->resource, (int)$r, (int)$g, (int)$b); |
664 | } |
665 | } |
666 | |
667 | /** |
668 | * Output the image |
669 | * |
670 | * @return string |
671 | */ |
672 | public function __toString() |
673 | { |
674 | $this->sendHeaders(); |
675 | $this->generateImage(100); |
676 | return ''; |
677 | } |
678 | |
679 | /** |
680 | * Copy the image resource to the image output resource with the set parameters |
681 | * |
682 | * @param int $w |
683 | * @param int $h |
684 | * @param int $x |
685 | * @param int $y |
686 | * @return void |
687 | */ |
688 | protected function copyImage($w, $h, $x = 0, $y = 0) |
689 | { |
690 | $result = imagecreatetruecolor($w, $h); |
691 | imagecopyresampled($result, $this->resource, 0, 0, $x, $y, $w, $h, $this->width, $this->height); |
692 | |
693 | if ($this->indexed) { |
694 | imagetruecolortopalette($result, false, 255); |
695 | } |
696 | |
697 | $this->resource = $result; |
698 | $this->width = imagesx($this->resource); |
699 | $this->height = imagesy($this->resource); |
700 | } |
701 | |
702 | /** |
703 | * Parse the image data |
704 | * |
705 | * @param array $size |
706 | * @param string $data |
707 | * @return void |
708 | */ |
709 | protected function parseImage(array $size, $data) |
710 | { |
711 | $this->width = $size[0]; |
712 | $this->height = $size[1]; |
713 | |
714 | if ((($size[2] == IMAGETYPE_JPEG) || ($size[2] == IMAGETYPE_JPEG2000)) && isset($size['channels'])) { |
715 | switch ($size['channels']) { |
716 | case 1: |
717 | $this->colorspace = self::IMAGE_GRAY; |
718 | break; |
719 | case 3: |
720 | $this->colorspace = self::IMAGE_RGB; |
721 | break; |
722 | case 4: |
723 | $this->colorspace = self::IMAGE_CMYK; |
724 | break; |
725 | } |
726 | $this->format = 'jpg'; |
727 | } else if ($size[2] == IMAGETYPE_PNG) { |
728 | switch (ord($data[25])) { |
729 | case 0: |
730 | case 4: |
731 | $this->colorspace = self::IMAGE_GRAY; |
732 | break; |
733 | case 2: |
734 | case 6: |
735 | $this->colorspace = self::IMAGE_RGB; |
736 | break; |
737 | case 3: |
738 | $this->colorspace = self::IMAGE_RGB; |
739 | $this->indexed = true; |
740 | break; |
741 | } |
742 | $this->format = 'png'; |
743 | } else if ($size[2] == IMAGETYPE_GIF) { |
744 | $this->colorspace = self::IMAGE_RGB; |
745 | $this->indexed = true; |
746 | $this->format = 'gif'; |
747 | } |
748 | } |
749 | |
750 | /** |
751 | * Parse the image data |
752 | * |
753 | * @param int $quality |
754 | * @param string $to |
755 | * @return void |
756 | */ |
757 | protected function generateImage($quality, $to = null) |
758 | { |
759 | switch ($this->format) { |
760 | case 'jpg': |
761 | case 'jpeg': |
762 | imagejpeg($this->resource, $to, (int)$quality); |
763 | break; |
764 | case 'png': |
765 | $quality = ($quality < 10) ? 9 : 10 - round(($quality / 10), PHP_ROUND_HALF_DOWN); |
766 | imagepng($this->resource, $to, (int)$quality); |
767 | break; |
768 | case 'gif': |
769 | imagegif($this->resource, $to); |
770 | break; |
771 | } |
772 | } |
773 | |
774 | } |