1 | <?php |
||||||
2 | /** |
||||||
3 | * This file is part of the O2System Framework package. |
||||||
4 | * |
||||||
5 | * For the full copyright and license information, please view the LICENSE |
||||||
6 | * file that was distributed with this source code. |
||||||
7 | * |
||||||
8 | * @author Steeve Andrian Salim |
||||||
9 | * @copyright Copyright (c) Steeve Andrian Salim |
||||||
10 | */ |
||||||
11 | |||||||
12 | // ------------------------------------------------------------------------ |
||||||
13 | |||||||
14 | namespace O2System\Image; |
||||||
15 | |||||||
16 | // ------------------------------------------------------------------------ |
||||||
17 | |||||||
18 | use O2System\Image\Abstracts\AbstractDriver; |
||||||
19 | use O2System\Image\Abstracts\AbstractWatermark; |
||||||
20 | use O2System\Image\DataStructures\Config; |
||||||
21 | use O2System\Image\Optimizers\Imageoptim; |
||||||
22 | use O2System\Spl\Exceptions\Runtime\FileNotFoundException; |
||||||
23 | |||||||
24 | /** |
||||||
25 | * Class Manipulation |
||||||
26 | * |
||||||
27 | * @package O2System\Image |
||||||
28 | */ |
||||||
29 | class Manipulation |
||||||
30 | { |
||||||
31 | /** |
||||||
32 | * Manipulation::ROTATE_CW |
||||||
33 | * |
||||||
34 | * Clock wise image rotation degrees. |
||||||
35 | * |
||||||
36 | * @var int |
||||||
37 | */ |
||||||
38 | const ROTATE_CW = 90; |
||||||
39 | |||||||
40 | /** |
||||||
41 | * Manipulation::ROTATE_CCW |
||||||
42 | * |
||||||
43 | * Counter clock wise image rotation degrees. |
||||||
44 | * |
||||||
45 | * @var int |
||||||
46 | */ |
||||||
47 | const ROTATE_CCW = -90; |
||||||
48 | |||||||
49 | /** |
||||||
50 | * Manipulation::FLIP_HORIZONTAL |
||||||
51 | * |
||||||
52 | * Flip image with horizontal axis. |
||||||
53 | * |
||||||
54 | * @var int |
||||||
55 | */ |
||||||
56 | const FLIP_HORIZONTAL = 1; |
||||||
57 | |||||||
58 | /** |
||||||
59 | * Manipulation::FLIP_VERTICAL |
||||||
60 | * |
||||||
61 | * Flip image with vertical axis. |
||||||
62 | * |
||||||
63 | * @var int |
||||||
64 | */ |
||||||
65 | const FLIP_VERTICAL = 2; |
||||||
66 | |||||||
67 | /** |
||||||
68 | * Manipulation::FLIP_BOTH |
||||||
69 | * |
||||||
70 | * Flip image with horizontal and vertical axis. |
||||||
71 | * |
||||||
72 | * @var int |
||||||
73 | */ |
||||||
74 | const FLIP_BOTH = 3; |
||||||
75 | |||||||
76 | /** |
||||||
77 | * Manipulation::ORIENTATION_AUTO |
||||||
78 | * |
||||||
79 | * Auto image orientation. |
||||||
80 | * |
||||||
81 | * @var string |
||||||
82 | */ |
||||||
83 | const ORIENTATION_AUTO = 'AUTO'; |
||||||
84 | |||||||
85 | /** |
||||||
86 | * Manipulation::ORIENTATION_LANDSCAPE |
||||||
87 | * |
||||||
88 | * Landscape image orientation. |
||||||
89 | * |
||||||
90 | * @var string |
||||||
91 | */ |
||||||
92 | const ORIENTATION_LANDSCAPE = 'LANDSCAPE'; |
||||||
93 | |||||||
94 | /** |
||||||
95 | * Manipulation::DIRECTIVE_UP |
||||||
96 | * |
||||||
97 | * If the target image size is larger than the size of the source image then the image source size |
||||||
98 | * will be resized according to the target image size. But if the target image size is smaller than |
||||||
99 | * the size of the source image then the resulting image size will match the size of the image source. |
||||||
100 | * In other words the target image size should not be smaller than the size of the source image. |
||||||
101 | * |
||||||
102 | * @var string |
||||||
103 | */ |
||||||
104 | const DIRECTIVE_UP = 'UP'; |
||||||
105 | |||||||
106 | /** |
||||||
107 | * Manipulation::DIRECTIVE_DOWN |
||||||
108 | * |
||||||
109 | * If the target image size is smaller than the size of the source image then the image source size |
||||||
110 | * will be resized according to the target image size. But if the target image size is larger than |
||||||
111 | * the size of the source image then the resulting image size will match the size of the image source. |
||||||
112 | * In other words the target image size can not be larger than the size of the image source. |
||||||
113 | */ |
||||||
114 | const DIRECTIVE_DOWN = 'DOWN'; |
||||||
115 | |||||||
116 | /** |
||||||
117 | * Manipulation::DIRECTIVE_RATIO |
||||||
118 | * |
||||||
119 | * The source image size will always resized according to the target image size and according to aspect ratio. |
||||||
120 | * |
||||||
121 | * @var string |
||||||
122 | */ |
||||||
123 | const DIRECTIVE_RATIO = 'RATIO'; |
||||||
124 | |||||||
125 | /** |
||||||
126 | * Manipulation::ORIENTATION_PORTRAIT |
||||||
127 | * |
||||||
128 | * Landscape image orientation. |
||||||
129 | * |
||||||
130 | * @var string |
||||||
131 | */ |
||||||
132 | const ORIENTATION_PORTRAIT = 'PORTRAIT'; |
||||||
133 | |||||||
134 | /** |
||||||
135 | * Manipulation::ORIENTATION_SQUARE |
||||||
136 | * |
||||||
137 | * Landscape image orientation. |
||||||
138 | * |
||||||
139 | * @var string |
||||||
140 | */ |
||||||
141 | const ORIENTATION_SQUARE = 'SQUARE'; |
||||||
142 | |||||||
143 | /** |
||||||
144 | * Manipulation::WATERMARK_CENTER |
||||||
145 | * |
||||||
146 | * Watermark center position. |
||||||
147 | * |
||||||
148 | * @var string |
||||||
149 | */ |
||||||
150 | const WATERMARK_CENTER = 'CENTER'; |
||||||
151 | |||||||
152 | /** |
||||||
153 | * Manipulation::WATERMARK_MIDDLE_LEFT |
||||||
154 | * |
||||||
155 | * Watermark middle left position. |
||||||
156 | * |
||||||
157 | * @var string |
||||||
158 | */ |
||||||
159 | const WATERMARK_MIDDLE_LEFT = 'MIDDLE_LEFT'; |
||||||
160 | |||||||
161 | /** |
||||||
162 | * Manipulation::WATERMARK_MIDDLE_RIGHT |
||||||
163 | * |
||||||
164 | * Watermark middle right position. |
||||||
165 | * |
||||||
166 | * @var string |
||||||
167 | */ |
||||||
168 | const WATERMARK_MIDDLE_RIGHT = 'MIDDLE_RIGHT'; |
||||||
169 | |||||||
170 | /** |
||||||
171 | * Manipulation::WATERMARK_MIDDLE_TOP |
||||||
172 | * |
||||||
173 | * Watermark middle top position. |
||||||
174 | * |
||||||
175 | * @var string |
||||||
176 | */ |
||||||
177 | const WATERMARK_MIDDLE_TOP = 'MIDDLE_TOP'; |
||||||
178 | |||||||
179 | /** |
||||||
180 | * Manipulation::WATERMARK_MIDDLE_BOTTOM |
||||||
181 | * |
||||||
182 | * Watermark middle bottom position. |
||||||
183 | * |
||||||
184 | * @var string |
||||||
185 | */ |
||||||
186 | const WATERMARK_MIDDLE_BOTTOM = 'MIDDLE_BOTTOM'; |
||||||
187 | |||||||
188 | /** |
||||||
189 | * Manipulation::WATERMARK_TOP_LEFT |
||||||
190 | * |
||||||
191 | * Watermark top left position. |
||||||
192 | * |
||||||
193 | * @var string |
||||||
194 | */ |
||||||
195 | const WATERMARK_TOP_LEFT = 'TOP_LEFT'; |
||||||
196 | |||||||
197 | /** |
||||||
198 | * Manipulation::WATERMARK_TOP_RIGHT |
||||||
199 | * |
||||||
200 | * Watermark top right position. |
||||||
201 | * |
||||||
202 | * @var string |
||||||
203 | */ |
||||||
204 | const WATERMARK_TOP_RIGHT = 'TOP_RIGHT'; |
||||||
205 | |||||||
206 | /** |
||||||
207 | * Manipulation::WATERMARK_BOTTOM_LEFT |
||||||
208 | * |
||||||
209 | * Watermark bottom left position. |
||||||
210 | * |
||||||
211 | * @var string |
||||||
212 | */ |
||||||
213 | const WATERMARK_BOTTOM_LEFT = 'BOTTOM_LEFT'; |
||||||
214 | |||||||
215 | /** |
||||||
216 | * Manipulation::WATERMARK_BOTTOM_RIGHT |
||||||
217 | * |
||||||
218 | * Watermark bottom right position. |
||||||
219 | * |
||||||
220 | * @var string |
||||||
221 | */ |
||||||
222 | const WATERMARK_BOTTOM_RIGHT = 'BOTTOM_RIGHT'; |
||||||
223 | |||||||
224 | /** |
||||||
225 | * Manipulation::$config |
||||||
226 | * |
||||||
227 | * Manipulation image config. |
||||||
228 | * |
||||||
229 | * @var Config |
||||||
230 | */ |
||||||
231 | protected $config; |
||||||
232 | |||||||
233 | /** |
||||||
234 | * Manipulation::$driver |
||||||
235 | * |
||||||
236 | * Manipulation image driver. |
||||||
237 | * |
||||||
238 | * @var AbstractDriver |
||||||
239 | */ |
||||||
240 | protected $driver; |
||||||
241 | |||||||
242 | // ------------------------------------------------------------------------ |
||||||
243 | |||||||
244 | /** |
||||||
245 | * Manipulation::__construct |
||||||
246 | * |
||||||
247 | * @param \O2System\Image\DataStructures\Config $config |
||||||
248 | */ |
||||||
249 | public function __construct(Config $config = null) |
||||||
250 | { |
||||||
251 | language() |
||||||
252 | ->addFilePath(__DIR__ . DIRECTORY_SEPARATOR) |
||||||
253 | ->loadFile('image'); |
||||||
254 | |||||||
255 | $this->config = is_null($config) ? new Config() : $config; |
||||||
256 | |||||||
257 | if ($this->config->offsetExists('driver')) { |
||||||
258 | $this->loadDriver($this->config->driver); |
||||||
0 ignored issues
–
show
Bug
Best Practice
introduced
by
![]() |
|||||||
259 | } |
||||||
260 | } |
||||||
261 | |||||||
262 | // ------------------------------------------------------------------------ |
||||||
263 | |||||||
264 | /** |
||||||
265 | * Manipulation::loadDriver |
||||||
266 | * |
||||||
267 | * Internal driver loader. |
||||||
268 | * |
||||||
269 | * @param string $driverOffset Driver offset name. |
||||||
270 | * |
||||||
271 | * @return bool |
||||||
272 | */ |
||||||
273 | protected function loadDriver($driverOffset) |
||||||
274 | { |
||||||
275 | $driverClassName = '\O2System\Image\Drivers\\' . ucfirst($driverOffset) . 'Driver'; |
||||||
276 | |||||||
277 | if (class_exists($driverClassName)) { |
||||||
278 | if ($this->config->offsetExists($driverOffset)) { |
||||||
279 | $config = $this->config[ $driverOffset ]; |
||||||
280 | } else { |
||||||
281 | $config = $this->config->getArrayCopy(); |
||||||
282 | } |
||||||
283 | |||||||
284 | if (isset($config[ 'engine' ])) { |
||||||
285 | unset($config[ 'engine' ]); |
||||||
286 | } |
||||||
287 | |||||||
288 | $this->driver = new $driverClassName(); |
||||||
289 | |||||||
290 | return true; |
||||||
291 | } |
||||||
292 | |||||||
293 | return false; |
||||||
294 | } |
||||||
295 | |||||||
296 | // ------------------------------------------------------------------------ |
||||||
297 | |||||||
298 | /** |
||||||
299 | * Manipulation::setDriver |
||||||
300 | * |
||||||
301 | * Manually set image manipulation library driver. |
||||||
302 | * |
||||||
303 | * @param \O2System\Image\Abstracts\AbstractDriver $imageDriver |
||||||
304 | * |
||||||
305 | * @return static |
||||||
306 | */ |
||||||
307 | public function setDriver(AbstractDriver $imageDriver) |
||||||
308 | { |
||||||
309 | $this->driver = $imageDriver; |
||||||
310 | |||||||
311 | return $this; |
||||||
312 | } |
||||||
313 | |||||||
314 | // ------------------------------------------------------------------------ |
||||||
315 | |||||||
316 | /** |
||||||
317 | * Manipulation::setImageFile |
||||||
318 | * |
||||||
319 | * Sets image for manipulation. |
||||||
320 | * |
||||||
321 | * @param string $imageFilePath Existing image file path. |
||||||
322 | * |
||||||
323 | * @return static |
||||||
324 | * @throws \O2System\Spl\Exceptions\Runtime\FileNotFoundException |
||||||
325 | */ |
||||||
326 | public function setImageFile($imageFilePath) |
||||||
327 | { |
||||||
328 | if ( ! $this->driver->setSourceImage($imageFilePath)) { |
||||||
329 | throw new FileNotFoundException('IMAGE_E_FILE_NOT_FOUND', 0, [$imageFilePath]); |
||||||
330 | } |
||||||
331 | |||||||
332 | // Create image source resource |
||||||
333 | $this->driver->createFromSource(); |
||||||
334 | |||||||
335 | return $this; |
||||||
336 | } |
||||||
337 | |||||||
338 | // ------------------------------------------------------------------------ |
||||||
339 | |||||||
340 | /** |
||||||
341 | * Manipulation::setImageUrl |
||||||
342 | * |
||||||
343 | * @param string $imageUrl |
||||||
344 | * |
||||||
345 | * @return static |
||||||
346 | * @throws \O2System\Spl\Exceptions\Runtime\FileNotFoundException |
||||||
347 | */ |
||||||
348 | public function setImageUrl($imageUrl) |
||||||
349 | { |
||||||
350 | if (false === ($imageString = file_get_contents($imageUrl))) { |
||||||
351 | throw new FileNotFoundException('IMAGE_E_URL_INVALID', 0, [$imageUrl]); |
||||||
352 | } |
||||||
353 | |||||||
354 | // Create image source resource |
||||||
355 | $this->driver->createFromString($imageString); |
||||||
356 | |||||||
357 | return $this; |
||||||
358 | } |
||||||
359 | |||||||
360 | // ------------------------------------------------------------------------ |
||||||
361 | |||||||
362 | /** |
||||||
363 | * Manipulation::setImageString |
||||||
364 | * |
||||||
365 | * @param string $imageString Image string. |
||||||
366 | * @param bool $base64 Use base64_decode to decode the image string. |
||||||
367 | * |
||||||
368 | * @return static |
||||||
369 | * @throws \O2System\Spl\Exceptions\Runtime\FileNotFoundException |
||||||
370 | */ |
||||||
371 | public function setImageString($imageString, $base64 = false) |
||||||
372 | { |
||||||
373 | if ($base64) { |
||||||
374 | if (false === ($imageString = base64_decode($imageString, true))) { |
||||||
375 | throw new FileNotFoundException('IMAGE_E_STRING_INVALID'); |
||||||
376 | } |
||||||
377 | } |
||||||
378 | |||||||
379 | // Create image source resource |
||||||
380 | $this->driver->createFromString($imageString); |
||||||
381 | |||||||
382 | return $this; |
||||||
383 | } |
||||||
384 | |||||||
385 | // ------------------------------------------------------------------------ |
||||||
386 | |||||||
387 | /** |
||||||
388 | * Manipulation::rotateImage |
||||||
389 | * |
||||||
390 | * Rotate an image. |
||||||
391 | * |
||||||
392 | * @param int $degrees Image rotation degrees. |
||||||
393 | * |
||||||
394 | * @return bool |
||||||
395 | */ |
||||||
396 | public function rotateImage($degrees) |
||||||
397 | { |
||||||
398 | if (is_int($degrees)) { |
||||||
399 | $this->driver->rotate($degrees); |
||||||
400 | |||||||
401 | return true; |
||||||
402 | } |
||||||
403 | |||||||
404 | return false; |
||||||
405 | } |
||||||
406 | |||||||
407 | // ------------------------------------------------------------------------ |
||||||
408 | |||||||
409 | /** |
||||||
410 | * Manipulation::flipImage |
||||||
411 | * |
||||||
412 | * Flip an image. |
||||||
413 | * |
||||||
414 | * @param int $axis Image flip axis. |
||||||
415 | * |
||||||
416 | * @return bool |
||||||
417 | */ |
||||||
418 | public function flipImage($axis) |
||||||
419 | { |
||||||
420 | if (in_array($axis, [self::FLIP_HORIZONTAL, self::FLIP_VERTICAL, self::FLIP_BOTH])) { |
||||||
421 | |||||||
422 | $this->driver->flip($axis); |
||||||
423 | |||||||
424 | return true; |
||||||
425 | } |
||||||
426 | |||||||
427 | return false; |
||||||
428 | } |
||||||
429 | |||||||
430 | // ------------------------------------------------------------------------ |
||||||
431 | |||||||
432 | /** |
||||||
433 | * Manipulation::resizeImage |
||||||
434 | * |
||||||
435 | * Scale an image using the given new width and height |
||||||
436 | * |
||||||
437 | * @param int $newWidth The width to scale the image to. |
||||||
438 | * @param int $newHeight The height to scale the image to. |
||||||
439 | * @param bool $crop The image autocrop |
||||||
440 | * |
||||||
441 | * @return bool |
||||||
442 | */ |
||||||
443 | public function resizeImage($newWidth, $newHeight, $crop = false) |
||||||
444 | { |
||||||
445 | $newWidth = intval($newWidth); |
||||||
446 | $newHeight = intval($newHeight); |
||||||
447 | $resampleImageFile = $this->driver->getSourceImageFile(); |
||||||
448 | $resampleDimension = $resampleImageFile->getDimension(); |
||||||
449 | $resampleDimension->maintainAspectRatio = $this->config->offsetGet('maintainAspectRatio'); |
||||||
450 | |||||||
451 | if ($newWidth == $newHeight) { |
||||||
452 | $this->driver->setResampleImage($resampleImageFile->withDimension( |
||||||
453 | $resampleDimension |
||||||
454 | ->withOrientation('SQUARE') |
||||||
455 | ->withFocus('CENTER') |
||||||
456 | ->withSize($newWidth, $newHeight) |
||||||
457 | )); |
||||||
458 | |||||||
459 | return $this->driver->resize(true); |
||||||
460 | } else { |
||||||
461 | $this->driver->setResampleImage($resampleImageFile->withDimension( |
||||||
462 | $resampleDimension |
||||||
463 | ->withDirective($this->config->offsetGet('scaleDirective')) |
||||||
464 | ->withOrientation($this->config->offsetGet('orientation')) |
||||||
465 | ->withFocus($this->config->offsetGet('focus')) |
||||||
466 | ->withSize($newWidth, $newHeight) |
||||||
467 | )); |
||||||
468 | |||||||
469 | return $this->driver->resize($crop); |
||||||
470 | } |
||||||
471 | } |
||||||
472 | |||||||
473 | // ------------------------------------------------------------------------ |
||||||
474 | |||||||
475 | /** |
||||||
476 | * Manipulation::scaleImage |
||||||
477 | * |
||||||
478 | * Scale an image using the percentage image scale. |
||||||
479 | * |
||||||
480 | * @param int $newScale The percentage to scale the image to. |
||||||
481 | * |
||||||
482 | * @return bool |
||||||
483 | */ |
||||||
484 | public function scaleImage($newScale) |
||||||
485 | { |
||||||
486 | $resampleImageFile = $this->driver->getSourceImageFile(); |
||||||
487 | $resampleDimension = $resampleImageFile->getDimension(); |
||||||
488 | $resampleDimension->maintainAspectRatio = $this->config->offsetGet('maintainAspectRatio'); |
||||||
489 | |||||||
490 | $this->driver->setResampleImage($resampleImageFile->withDimension( |
||||||
491 | $resampleDimension |
||||||
492 | ->withScale($newScale) |
||||||
493 | )); |
||||||
494 | |||||||
495 | return $this->driver->scale(); |
||||||
496 | } |
||||||
497 | |||||||
498 | // ------------------------------------------------------------------------ |
||||||
499 | |||||||
500 | /** |
||||||
501 | * Manipulation::watermarkImage |
||||||
502 | * |
||||||
503 | * Watermark an image using Text or Overlay. |
||||||
504 | * |
||||||
505 | * @param \O2System\Image\Abstracts\AbstractWatermark $watermark |
||||||
506 | */ |
||||||
507 | public function watermarkImage(AbstractWatermark $watermark) |
||||||
508 | { |
||||||
509 | $this->driver->watermark($watermark); |
||||||
0 ignored issues
–
show
The method
watermark() does not exist on O2System\Image\Abstracts\AbstractDriver . Since it exists in all sub-types, consider adding an abstract or default implementation to O2System\Image\Abstracts\AbstractDriver .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
510 | } |
||||||
511 | |||||||
512 | // ------------------------------------------------------------------------ |
||||||
513 | |||||||
514 | /** |
||||||
515 | * Manipulation::cropImage |
||||||
516 | * |
||||||
517 | * Crop an image using new Dimension. |
||||||
518 | * |
||||||
519 | * @param \O2System\Image\Dimension $dimension |
||||||
520 | */ |
||||||
521 | public function cropImage(Dimension $dimension) |
||||||
522 | { |
||||||
523 | $this->driver->crop($dimension); |
||||||
0 ignored issues
–
show
The method
crop() does not exist on O2System\Image\Abstracts\AbstractDriver . Since it exists in all sub-types, consider adding an abstract or default implementation to O2System\Image\Abstracts\AbstractDriver .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
524 | } |
||||||
525 | |||||||
526 | // ------------------------------------------------------------------------ |
||||||
527 | |||||||
528 | /** |
||||||
529 | * Manipulation::getBlobImage |
||||||
530 | * |
||||||
531 | * Gets image blob string. |
||||||
532 | * |
||||||
533 | * @return string |
||||||
534 | */ |
||||||
535 | public function getBlobImage() |
||||||
536 | { |
||||||
537 | return $this->driver->blob($this->config->offsetGet('quality')); |
||||||
538 | } |
||||||
539 | |||||||
540 | // ------------------------------------------------------------------------ |
||||||
541 | |||||||
542 | /** |
||||||
543 | * Manipulation::displayImage |
||||||
544 | * |
||||||
545 | * Display an image. |
||||||
546 | * |
||||||
547 | * @return void |
||||||
548 | */ |
||||||
549 | public function displayImage($quality = null, $mime = null) |
||||||
550 | { |
||||||
551 | $quality = empty($quality) ? $this->config->offsetGet('quality') : $quality; |
||||||
552 | |||||||
553 | $filename = pathinfo($this->driver->getSourceImageFile()->getBasename(), PATHINFO_FILENAME); |
||||||
554 | $extension = pathinfo($this->driver->getSourceImageFile()->getBasename(), PATHINFO_EXTENSION); |
||||||
555 | |||||||
556 | if (empty($mime)) { |
||||||
557 | $mime = $this->driver->getSourceImageFile()->getMime(); |
||||||
558 | $mime = is_array($mime) ? $mime[ 0 ] : $mime; |
||||||
559 | |||||||
560 | $extension = $this->driver->getMimeExtension($mime); |
||||||
561 | } |
||||||
562 | |||||||
563 | if ($this->saveImage($tempImageFilePath = rtrim(sys_get_temp_dir(), |
||||||
564 | DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename . '.' . $extension, |
||||||
0 ignored issues
–
show
Are you sure
$extension of type false|mixed|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
565 | $quality) |
||||||
566 | ) { |
||||||
567 | $imageBlob = readfile($tempImageFilePath); |
||||||
568 | unlink($tempImageFilePath); |
||||||
569 | } |
||||||
570 | |||||||
571 | header('Content-Transfer-Encoding: binary'); |
||||||
572 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT'); |
||||||
573 | header('Content-Disposition: filename=' . $filename . '.' . $extension); |
||||||
574 | header('Content-Type: ' . $mime); |
||||||
575 | |||||||
576 | echo $imageBlob; |
||||||
577 | exit(0); |
||||||
578 | } |
||||||
579 | |||||||
580 | // ------------------------------------------------------------------------ |
||||||
581 | |||||||
582 | /** |
||||||
583 | * Manipulation::saveImage |
||||||
584 | * |
||||||
585 | * Save an manipulated image into new image file. |
||||||
586 | * |
||||||
587 | * @param string $saveImageFilePath Save image file path. |
||||||
588 | * |
||||||
589 | * @return bool |
||||||
590 | */ |
||||||
591 | public function saveImage($saveImageFilePath, $quality = null) |
||||||
592 | { |
||||||
593 | $quality = empty($quality) ? $this->config->offsetGet('quality') : $quality; |
||||||
594 | $optimizerConfig = $this->config->offsetGet('optimizer'); |
||||||
595 | |||||||
596 | if ($this->driver->save($saveImageFilePath, $quality)) { |
||||||
597 | if ($optimizerConfig === 'default') { |
||||||
598 | $optimizer = new Optimizer(); |
||||||
599 | $optimizer->optimize($saveImageFilePath); |
||||||
600 | } elseif ( ! empty($optimizerConfig[ 'factory' ])) { |
||||||
601 | $factory = $optimizerConfig[ 'factory' ]; |
||||||
602 | $optimizer = new Optimizer(); |
||||||
603 | |||||||
604 | switch ($factory) { |
||||||
605 | case 'imageoptim'; |
||||||
606 | $factory = new Imageoptim(); |
||||||
607 | $factory->setUsername($optimizerConfig[ 'username' ]); |
||||||
608 | $optimizer->setImageFactory($factory); |
||||||
609 | break; |
||||||
610 | } |
||||||
611 | |||||||
612 | $optimizer->optimize($saveImageFilePath); |
||||||
613 | } |
||||||
614 | |||||||
615 | return true; |
||||||
616 | } |
||||||
617 | |||||||
618 | return false; |
||||||
619 | } |
||||||
620 | } |