GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

GraphicsmagickDriver::scale()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 0
dl 0
loc 22
rs 9.9
c 0
b 0
f 0
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\Drivers;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Image\Abstracts\AbstractDriver;
19
use O2System\Image\Abstracts\AbstractWatermark;
20
use O2System\Image\Dimension;
21
use O2System\Image\Watermark\Overlay;
22
use O2System\Image\Watermark\Text;
23
use O2System\Spl\Exceptions\Logic\BadFunctionCall\BadPhpExtensionCallException;
24
25
/**
26
 * Class GraphicsmagickDriver
27
 *
28
 * @package O2System\Image\Drivers
29
 */
30
class GraphicsmagickDriver extends AbstractDriver
31
{
32
    /**
33
     * GraphicsmagickDriver::__construct
34
     *
35
     * @throws \O2System\Spl\Exceptions\Logic\BadFunctionCall\BadPhpExtensionCallException
36
     */
37
    public function __construct()
38
    {
39
        if ( ! class_exists('Gmagick', false)) {
40
            throw new BadPhpExtensionCallException('IMAGE_E_PHP_EXTENSION', 0, ['gmagick']);
41
        }
42
    }
43
44
    // ------------------------------------------------------------------------
45
46
    /**
47
     * GraphicsmagickDriver::__destruct
48
     */
49
    public function __destruct()
50
    {
51
        if (is_object($this->sourceImageResource)) {
52
            $this->sourceImageResource->destroy();
53
        }
54
55
        if (is_object($this->resampleImageResource)) {
56
            $this->resampleImageResource->destroy();
57
        }
58
    }
59
60
    // ------------------------------------------------------------------------
61
62
    /**
63
     * GraphicsmagickDriver::createFromString
64
     *
65
     * Create an image resource from image string.
66
     *
67
     * @param string $imageString Image string.
68
     *
69
     * @return bool
70
     * @throws \GmagickException
71
     */
72
    public function createFromString($imageString)
73
    {
74
        $this->sourceImageResource = new \Gmagick();
75
76
        try {
77
78
            $this->sourceImageResource->readimageblob($imageString);
79
80
            return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the return type mandated by O2System\Image\Abstracts...ver::createFromString() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
81
82
        } catch (\GmagickException $e) {
83
84
            $this->errors[ $e->getCode() ] = $e->getMessage();
85
86
        }
87
88
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by O2System\Image\Abstracts...ver::createFromString() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
89
    }
90
91
    // ------------------------------------------------------------------------
92
93
    /**
94
     * GraphicsmagickDriver::rotate
95
     *
96
     * Rotate an image with a given angle.
97
     *
98
     * @param float $degrees Image rotation degrees.
99
     *
100
     * @return bool
101
     */
102
    public function rotate($degrees)
103
    {
104
        $resampleImageResource =& $this->getResampleImageResource();
105
106
        try {
107
108
            $resampleImageResource->rotateimage('#000000', $degrees);
109
110
            return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the return type mandated by O2System\Image\Abstracts\AbstractDriver::rotate() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
111
112
        } catch (\GmagickException $e) {
113
114
            $this->errors[ $e->getCode() ] = $e->getMessage();
115
116
        }
117
118
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by O2System\Image\Abstracts\AbstractDriver::rotate() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
119
    }
120
121
    // ------------------------------------------------------------------------
122
123
    /**
124
     * GraphicsmagickDriver::flip
125
     *
126
     * Flip an image with a given axis.
127
     *
128
     * @param int $axis Flip axis.
129
     *
130
     * @return bool
131
     */
132
    public function flip($axis)
133
    {
134
        $gdAxis = [
135
            1 => IMG_FLIP_HORIZONTAL,
136
            2 => IMG_FLIP_VERTICAL,
137
            3 => IMG_FLIP_BOTH,
138
        ];
139
140
        if (array_key_exists($axis, $gdAxis)) {
141
            $resampleImageResource =& $this->getResampleImageResource();
142
143
            try {
144
                switch ($axis) {
145
                    case 1:
146
                        $resampleImageResource->flopimage();
147
                        break;
148
                    case 2:
149
                        $resampleImageResource->flipimage();
150
                        break;
151
                    case 3:
152
                        $resampleImageResource->flopimage();
153
                        $resampleImageResource->flipimage();
154
                        break;
155
                }
156
157
                return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the return type mandated by O2System\Image\Abstracts\AbstractDriver::flip() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
158
159
            } catch (\GmagickException $e) {
160
161
                $this->errors[ $e->getCode() ] = $e->getMessage();
162
163
            }
164
        }
165
166
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by O2System\Image\Abstracts\AbstractDriver::flip() of void.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
167
    }
168
169
    // ------------------------------------------------------------------------
170
171
    /**
172
     * GraphicsmagickDriver::resize
173
     *
174
     * Resize an image using the given new width and height.
175
     *
176
     * @param bool $crop Perform auto crop or not
177
     *
178
     * @return bool
179
     */
180
    public function resize($crop = false)
181
    {
182
        if ($crop) {
183
            return $this->resizeCrop();
184
        } else {
185
            $sourceDimension = $this->sourceImageFile->getDimension();
186
            $resampleDimension = $this->resampleImageFile->getDimension();
187
188
            if (($sourceDimension->getWidth() <= $resampleDimension->getWidth()) && ($sourceDimension->getHeight() <= $resampleDimension->getHeight())) {
189
                return true;
190
            } //no resizing needed
191
192
            //try max width first...
193
            $resizeRatio = $resampleDimension->getWidth() / $sourceDimension->getWidth();
194
            $resizeWidth = $resampleDimension->getWidth();
195
            $resizeHeight = $sourceDimension->getHeight() * $resizeRatio;
196
197
            //if that didn't work
198
            if ($resizeHeight > $resampleDimension->getHeight()) {
199
                $resizeRatio = $resampleDimension->getHeight() / $sourceDimension->getHeight();
200
                $resizeHeight = $resampleDimension->getHeight();
201
                $resizeWidth = $sourceDimension->getWidth() * $resizeRatio;
202
            }
203
204
            $resampleImageResource =& $this->getResampleImageResource();
205
206
            try {
207
                $resampleImageResource->resizeimage($resizeWidth, $resizeHeight,
208
                    \Gmagick::FILTER_CATROM, 0.9, true);
209
210
                return true;
211
212
            } catch (\GmagickException $e) {
213
214
                $this->errors[ $e->getCode() ] = $e->getMessage();
215
216
                return false;
217
            }
218
        }
219
    }
220
221
    // ------------------------------------------------------------------------
222
223
    /**
224
     * GraphicsmagickDriver::resizeCrop
225
     *
226
     * @return bool
227
     */
228
    protected function resizeCrop()
229
    {
230
        $sourceDimension = $this->sourceImageFile->getDimension();
231
        $resampleDimension = $this->resampleImageFile->getDimension();
232
233
        //try max width first...
234
        $resizeRatio = $resampleDimension->getWidth() / $sourceDimension->getWidth();
235
        $resizeWidth = $resampleDimension->getWidth();
236
        $resizeHeight = $sourceDimension->getHeight() * $resizeRatio;
237
238
        //if that didn't work
239
        if ($resizeHeight > $resampleDimension->getHeight()) {
240
            $resizeRatio = $resampleDimension->getHeight() / $sourceDimension->getHeight();
241
            $resizeHeight = $resampleDimension->getHeight();
242
            $resizeWidth = $sourceDimension->getWidth() * $resizeRatio;
243
        }
244
245
        $resampleImageResource =& $this->getResampleImageResource();
246
247
        if ($resampleDimension->getOrientation() === 'SQUARE') {
248
249
            try {
250
251
                $resampleImageResource->resizeimage($resizeWidth, $resizeHeight, \Gmagick::FILTER_LANCZOS, 0.9, false);
252
                $resampleAxis = new Dimension\Axis(
253
                    ($resizeWidth - $resampleDimension->getWidth()) / 2,
254
                    ($resizeHeight - $resampleDimension->getWidth()) / 2
255
                );
256
257
            } catch (\GmagickException $e) {
258
259
                $this->errors[ $e->getCode() ] = $e->getMessage();
260
261
                return false;
262
263
            }
264
        } else {
265
            switch ($resampleDimension->getFocus()) {
266
                default:
267
                case 'CENTER':
268
                    $resampleAxis = new Dimension\Axis(
269
                        ($sourceDimension->getWidth() / 2) - ($resizeWidth / 2),
270
                        ($sourceDimension->getHeight() / 2) - ($resizeHeight / 2)
271
                    );
272
                    break;
273
                case 'NORTH':
274
                    $resampleAxis = new Dimension\Axis(
275
                        ($sourceDimension->getWidth() - $resizeWidth) / 2,
276
                        0
277
                    );
278
                    break;
279
                case 'NORTHWEST':
280
                    $resampleAxis = new Dimension\Axis(
281
                        0,
282
                        0
283
                    );
284
                    break;
285
                case 'NORTHEAST':
286
                    $resampleAxis = new Dimension\Axis(
287
                        $sourceDimension->getWidth() - $resizeWidth,
288
                        0
289
                    );
290
                    break;
291
                case 'SOUTH':
292
                    $resampleAxis = new Dimension\Axis(
293
                        ($sourceDimension->getWidth() - $resizeWidth) / 2,
294
                        $sourceDimension->getHeight() - $resizeHeight
295
                    );
296
                    break;
297
                case 'SOUTHWEST':
298
                    $resampleAxis = new Dimension\Axis(
299
                        0,
300
                        $sourceDimension->getHeight() - $resizeHeight
301
                    );
302
                    break;
303
                case 'SOUTHEAST':
304
                    $resampleAxis = new Dimension\Axis(
305
                        $sourceDimension->getWidth() - $resizeWidth,
306
                        $sourceDimension->getHeight() - $resizeHeight
307
                    );
308
                    break;
309
                case 'WEST':
310
                    $resampleAxis = new Dimension\Axis(
311
                        0,
312
                        ($sourceDimension->getHeight() - $resizeHeight) / 2
313
                    );
314
                    break;
315
                case 'EAST':
316
                    $resampleAxis = new Dimension\Axis(
317
                        $sourceDimension->getWidth() - $resizeWidth,
318
                        ($sourceDimension->getHeight() - $resizeHeight) / 2
319
                    );
320
                    break;
321
            }
322
323
            try {
324
325
                $resampleImageResource->resizeimage($sourceDimension->getWidth(), $sourceDimension->getHeight(),
326
                    \Gmagick::FILTER_CATROM, 0.9, true);
327
328
            } catch (\GmagickException $e) {
329
330
                $this->errors[ $e->getCode() ] = $e->getMessage();
331
332
            }
333
        }
334
335
        return $this->crop($resampleDimension->withAxis($resampleAxis));
336
    }
337
338
    // ------------------------------------------------------------------------
339
340
    /**
341
     * GraphicsmagickDriver::crop
342
     *
343
     * Crop an image.
344
     *
345
     * @param \O2System\Image\Dimension $dimension
346
     *
347
     * @return bool
348
     */
349
    public function crop(Dimension $dimension)
350
    {
351
        $resampleImageResource =& $this->getResampleImageResource();
352
353
        try {
354
355
            $resampleImageResource->cropimage(
356
                $dimension->getWidth(),
357
                $dimension->getHeight(),
358
                $dimension->getAxis()->getX(),
359
                $dimension->getAxis()->getY()
360
            );
361
362
            return true;
363
364
        } catch (\GmagickException $e) {
365
366
            $this->errors[ $e->getCode() ] = $e->getMessage();
367
368
        }
369
370
        return false;
371
    }
372
373
    /**
374
     * GraphicsmagickDriver::watermark
375
     *
376
     * Watermark an image.
377
     *
378
     * @param \O2System\Image\Abstracts\AbstractWatermark $watermark
379
     *
380
     * @return bool
381
     * @throws \O2System\Spl\Exceptions\Logic\BadFunctionCall\BadPhpExtensionCallException
382
     */
383
    public function watermark(AbstractWatermark $watermark)
384
    {
385
        $resampleImageResource =& $this->getResampleImageResource();
386
387
        if ($watermark instanceof Text) {
388
389
            $draw = new \GmagickDraw();
390
            $draw->setFont($watermark->getFontPath());
391
            $draw->setFontSize($watermark->getFontSize());
392
            $draw->setFillColor($watermark->getFontColor());
393
394
            if (false !== ($textAxis = $watermark->getAxis())) {
0 ignored issues
show
introduced by
The condition false !== $textAxis = $watermark->getAxis() is always true.
Loading history...
395
                $draw->annotation($textAxis->getX(), $textAxis->getY(), $watermark->getString());
0 ignored issues
show
Bug introduced by
The method annotation() does not exist on GmagickDraw. Did you maybe mean annotate()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

395
                $draw->/** @scrutinizer ignore-call */ annotation($textAxis->getX(), $textAxis->getY(), $watermark->getString());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
396
            } else {
397
                switch ($watermark->getPosition()) {
398
                    default:
399
                    case 'MIDDLE_MIDDLE':
400
                    case 'MIDDLE':
401
                    case 'CENTER':
402
                        $draw->setgravity(\Gmagick::GRAVITY_CENTER);
403
                        break;
404
405
                    case 'MIDDLE_LEFT':
406
                        $draw->setgravity(\Gmagick::GRAVITY_WEST);
407
                        break;
408
409
                    case 'MIDDLE_RIGHT':
410
                        $draw->setgravity(\Gmagick::GRAVITY_EAST);
411
                        break;
412
413
                    case 'MIDDLE_TOP':
414
                        $draw->setgravity(\Gmagick::GRAVITY_NORTH);
415
                        break;
416
417
                    case 'MIDDLE_BOTTOM':
418
                        $draw->setgravity(\Gmagick::GRAVITY_SOUTH);
419
                        break;
420
421
                    case 'TOP_LEFT':
422
                        $draw->setgravity(\Gmagick::GRAVITY_NORTHWEST);
423
                        break;
424
425
                    case 'TOP_RIGHT':
426
                        $draw->setgravity(\Gmagick::GRAVITY_NORTHEAST);
427
                        break;
428
429
                    case 'BOTTOM_LEFT':
430
                        $draw->setgravity(\Gmagick::GRAVITY_SOUTHWEST);
431
                        break;
432
433
                    case 'BOTTOM_RIGHT':
434
                        $draw->setgravity(\Gmagick::GRAVITY_SOUTHEAST);
435
                        break;
436
                }
437
            }
438
439
            try {
440
441
                $resampleImageResource->annotateimage(
442
                    $draw,
443
                    $watermark->getPadding(),
444
                    $watermark->getPadding(),
445
                    $watermark->getAngle(),
446
                    $watermark->getString()
447
                );
448
449
                return true;
450
451
            } catch (\GmagickException $e) {
452
453
                $this->errors[ $e->getCode() ] = $e->getMessage();
454
455
            }
456
        } elseif ($watermark instanceof Overlay) {
457
            $watermarkImage = new self;
458
            $watermarkImage->setSourceImage($watermark->getImagePath());
459
            $watermarkImage->createFromSource();
460
461
            $watermarkImageFile = $watermarkImage->getSourceImageFile();
462
            $watermarkImageDimension = $watermarkImageFile->getDimension();
463
            $watermarkImageDimension->maintainAspectRatio = true;
464
465
            $resampleImageDimension = $this->resampleImageFile->getDimension();
466
467
            if (false === ($scale = $watermark->getImageScale())) {
0 ignored issues
show
introduced by
The condition false === $scale = $watermark->getImageScale() is always false.
Loading history...
468
                $scale = min(
469
                    round((($resampleImageDimension->getWidth() / 2) / $watermarkImageDimension->getWidth()) * 100),
470
                    round((($resampleImageDimension->getHeight() / 2) / $watermarkImageDimension->getHeight()) * 100)
471
                );
472
            }
473
474
            if ($scale > 0) {
475
                $watermarkImage->setResampleImage($watermarkImageFile->withDimension(
476
                    $watermarkImageDimension
477
                        ->withScale($scale)
478
                ));
479
            }
480
481
            $watermarkImageDimension = $watermarkImage->getResampleImageFile()->getDimension();
482
483
            if ($watermarkImage->scale()) {
484
                $watermarkImageResource = $watermarkImage->getResampleImageResource();
485
486
                if (false !== ($watermarkAxis = $watermark->getAxis())) {
0 ignored issues
show
introduced by
The condition false !== $watermarkAxis = $watermark->getAxis() is always true.
Loading history...
487
                    $watermarkImageAxisX = $watermarkAxis->getX();
488
                    $watermarkImageAxisY = $watermarkAxis->getY();
489
                } else {
490
                    switch ($watermark->getPosition()) {
491
                        default:
492
                        case 'MIDDLE_MIDDLE':
493
                        case 'MIDDLE':
494
                        case 'CENTER':
495
                            $watermarkImageAxisX = ($resampleImageDimension->getWidth() - $watermarkImageDimension->getWidth()) / 2;
496
                            $watermarkImageAxisY = ($resampleImageDimension->getHeight() - $watermarkImageDimension->getHeight()) / 2;
497
                            break;
498
499
                        case 'MIDDLE_LEFT':
500
                            $watermarkImageAxisX = $watermark->getPadding();
501
                            $watermarkImageAxisY = ($resampleImageDimension->getHeight() - $watermarkImageDimension->getHeight()) / 2;
502
                            break;
503
504
                        case 'MIDDLE_RIGHT':
505
                            $watermarkImageAxisX = $resampleImageDimension->getWidth() - ($watermarkImageDimension->getWidth() + $watermark->getPadding());
506
                            $watermarkImageAxisY = ($resampleImageDimension->getHeight() - $watermarkImageDimension->getHeight()) / 2;
507
                            break;
508
509
                        case 'MIDDLE_TOP':
510
                            $watermarkImageAxisX = ($resampleImageDimension->getWidth() - $watermarkImageDimension->getWidth()) / 2;
511
                            $watermarkImageAxisY = $watermarkImageDimension->getHeight() + $watermark->getPadding();
512
                            break;
513
514
                        case 'MIDDLE_BOTTOM':
515
                            $watermarkImageAxisX = ($resampleImageDimension->getWidth() - $watermarkImageDimension->getWidth()) / 2;
516
                            $watermarkImageAxisY = $resampleImageDimension->getHeight() - ($watermarkImageDimension->getHeight() + $watermark->getPadding());
517
                            break;
518
519
                        case 'TOP_LEFT':
520
                            $watermarkImageAxisX = $watermark->getPadding();
521
                            $watermarkImageAxisY = $watermarkImageDimension->getHeight() + $watermark->getPadding();
522
                            break;
523
524
                        case 'TOP_RIGHT':
525
                            $watermarkImageAxisX = $resampleImageDimension->getWidth() - ($watermarkImageDimension->getWidth() + $watermark->getPadding());
526
                            $watermarkImageAxisY = $watermarkImageDimension->getHeight() + $watermark->getPadding();
527
                            break;
528
529
                        case 'BOTTOM_LEFT':
530
                            $watermarkImageAxisX = $watermark->getPadding();
531
                            $watermarkImageAxisY = $resampleImageDimension->getHeight() - $watermarkImageDimension->getHeight() + $watermark->getPadding();
532
                            break;
533
534
                        case 'BOTTOM_RIGHT':
535
                            $watermarkImageAxisX = $resampleImageDimension->getWidth() - ($watermarkImageDimension->getWidth() + $watermark->getPadding());
536
                            $watermarkImageAxisY = $resampleImageDimension->getHeight() - ($watermarkImageDimension->getHeight() + $watermark->getPadding());
537
                            break;
538
                    }
539
                }
540
541
                try {
542
                    $resampleImageResource->compositeimage($watermarkImageResource, \Gmagick::COMPOSITE_OVER,
543
                        $watermarkImageAxisX,
544
                        $watermarkImageAxisY);
545
546
                    return true;
547
                } catch (\GmagickException $e) {
548
                    $this->errors[ $e->getCode() ] = $e->getMessage();
549
                }
550
            }
551
        }
552
553
        return false;
554
    }
555
556
    // ------------------------------------------------------------------------
557
558
    /**
559
     * GraphicsmagickDriver::createFromSource
560
     *
561
     * Create an image resource from source file.
562
     *
563
     * @return static
564
     */
565
    public function createFromSource()
566
    {
567
        $this->sourceImageResource = new \Gmagick($this->sourceImageFile->getRealPath());
568
    }
569
570
    // ------------------------------------------------------------------------
571
572
    /**
573
     * GraphicsmagickDriver::scale
574
     *
575
     * Scale an image with a given scale.
576
     *
577
     * @return bool
578
     */
579
    public function scale()
580
    {
581
        $resampleDimension = $this->resampleImageFile->getDimension();
582
        $resampleImageResource =& $this->getResampleImageResource();
583
584
        try {
585
586
            $resampleImageResource->scaleimage(
587
                $resampleDimension->getWidth(),
588
                $resampleDimension->getHeight(),
589
                true
590
            );
591
592
            return true;
593
594
        } catch (\GmagickException $e) {
595
596
            $this->errors[ $e->getCode() ] = $e->getMessage();
597
598
        }
599
600
        return false;
601
    }
602
603
    // ------------------------------------------------------------------------
604
605
    /**
606
     * GraphicsmagickDriver::display
607
     *
608
     * Display an image.
609
     *
610
     * @return void
611
     */
612
    public function display($quality = 100, $mime = null)
613
    {
614
        $filename = pathinfo($this->sourceImageFile->getBasename(), PATHINFO_FILENAME);
615
        $extension = pathinfo($this->sourceImageFile->getBasename(), PATHINFO_EXTENSION);
616
617
        if (empty($mime)) {
618
            $mime = $this->sourceImageFile->getMime();
619
            $mime = is_array($mime) ? $mime[ 0 ] : $mime;
620
621
            $extension = $this->getMimeExtension($mime);
622
        }
623
624
        header('Content-Disposition: filename=' . $filename . '.' . $extension);
0 ignored issues
show
Bug introduced by
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 ignore-type  annotation

624
        header('Content-Disposition: filename=' . $filename . '.' . /** @scrutinizer ignore-type */ $extension);
Loading history...
625
        header('Content-Transfer-Encoding: binary');
626
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
627
        header('Content-Type: ' . $mime);
628
629
        $blob = $this->blob($quality, $mime);
630
631
        header('ETag: ' . md5($blob));
632
633
        echo $blob;
634
635
        exit(0);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
636
    }
637
638
    // ------------------------------------------------------------------------
639
640
    /**
641
     * GraphicsmagickDriver::blob
642
     *
643
     * Returns image string blob.
644
     *
645
     * @return string
646
     */
647
    public function blob($quality = 100, $mime = null)
648
    {
649
        $imageBlob = '';
650
651
        $filename = pathinfo($this->sourceImageFile->getBasename(), PATHINFO_FILENAME);
652
        $extension = pathinfo($this->sourceImageFile->getBasename(), PATHINFO_EXTENSION);
653
654
        if (empty($mime)) {
655
            $mime = $this->sourceImageFile->getMime();
656
            $mime = is_array($mime) ? $mime[ 0 ] : $mime;
657
658
            $extension = $this->getMimeExtension($mime);
659
        }
660
661
        if ($this->save($tempImageFilePath = rtrim(sys_get_temp_dir(),
662
                DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename . '.' . $extension,
0 ignored issues
show
Bug introduced by
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 ignore-type  annotation

662
                DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename . '.' . /** @scrutinizer ignore-type */ $extension,
Loading history...
663
            $quality)
664
        ) {
665
            $imageBlob = readfile($tempImageFilePath);
666
            unlink($tempImageFilePath);
667
        }
668
669
        return $imageBlob;
670
    }
671
672
    // ------------------------------------------------------------------------
673
674
    /**
675
     * GraphicsmagickDriver::save
676
     *
677
     * Save an image.
678
     *
679
     * @param string $imageTargetFilePath
680
     * @param int    $quality
681
     *
682
     * @return bool
683
     */
684
    public function save($imageTargetFilePath, $quality = 100)
685
    {
686
        $resampleImageResource =& $this->getResampleImageResource();
687
        $resampleImageResource->setCompressionQuality($quality);
688
        $resampleImageResource->stripimage();
689
690
        $extension = pathinfo($imageTargetFilePath, PATHINFO_EXTENSION);
691
692
        switch ($extension) {
693
            case 'jpg':
694
            case 'jpeg':
695
                $resampleImageResource->setImageFormat('jpg');
696
                break;
697
698
            case 'gif':
699
                $resampleImageResource->setImageFormat('gif');
700
                break;
701
702
            case 'png':
703
                $resampleImageResource->setImageFormat('png');
704
                $resampleImageResource->setImageAlphaChannel(\Gmagick::ALPHACHANNEL_ACTIVATE);
0 ignored issues
show
Bug introduced by
The constant Gmagick::ALPHACHANNEL_ACTIVATE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
705
                $resampleImageResource->setBackgroundColor(new \GmagickPixel('transparent'));
706
                break;
707
708
            case 'webp':
709
                $resampleImageResource->setImageFormat('webp');
710
                $resampleImageResource->setImageAlphaChannel(\Gmagick::ALPHACHANNEL_ACTIVATE);
711
                $resampleImageResource->setBackgroundColor(new \GmagickPixel('transparent'));
712
                break;
713
        }
714
715
        try {
716
717
            $resampleImageResource->writeimage($imageTargetFilePath);
718
719
            return true;
720
721
        } catch (\GmagickException $e) {
722
723
            $this->errors[ $e->getCode() ] = $e->getMessage();
724
725
        }
726
727
        return false;
728
    }
729
}