5
5
*/
6
6
namespace Magento \Framework \Image \Adapter ;
7
7
8
- class ImageMagick extends \Magento \Framework \Image \Adapter \AbstractAdapter
8
+ use Magento \Framework \Exception \LocalizedException ;
9
+
10
+ /**
11
+ * Image adapter from ImageMagick
12
+ */
13
+ class ImageMagick extends AbstractAdapter
9
14
{
10
15
/**
11
16
* The blur factor where > 1 is blurry, < 1 is sharp
@@ -66,7 +71,7 @@ public function backgroundColor($color = null)
66
71
*
67
72
* @param string $filename
68
73
* @return void
69
- * @throws \Exception
74
+ * @throws \Magento\Framework\ Exception\LocalizedException
70
75
*/
71
76
public function open ($ filename )
72
77
{
@@ -77,7 +82,11 @@ public function open($filename)
77
82
try {
78
83
$ this ->_imageHandler = new \Imagick ($ this ->_fileName );
79
84
} catch (\ImagickException $ e ) {
80
- throw new \Exception (sprintf ('Unsupported image format. File: %s ' , $ this ->_fileName ), $ e ->getCode (), $ e );
85
+ throw new LocalizedException (
86
+ __ ('Unsupported image format. File: %1 ' , $ this ->_fileName ),
87
+ $ e ,
88
+ $ e ->getCode ()
89
+ );
81
90
}
82
91
83
92
$ this ->backgroundColor ();
@@ -86,12 +95,13 @@ public function open($filename)
86
95
87
96
/**
88
97
* Save image to specific path.
98
+ *
89
99
* If some folders of path does not exist they will be created
90
100
*
91
101
* @param null|string $destination
92
102
* @param null|string $newName
93
103
* @return void
94
- * @throws \Exception If destination path is not writable
104
+ * @throws \Magento\Framework\ Exception\LocalizedException If destination path is not writable
95
105
*/
96
106
public function save ($ destination = null , $ newName = null )
97
107
{
@@ -124,6 +134,8 @@ protected function _applyOptions()
124
134
}
125
135
126
136
/**
137
+ * Render image and return its binary contents
138
+ *
127
139
* @see \Magento\Framework\Image\Adapter\AbstractAdapter::getImage
128
140
* @return string
129
141
*/
@@ -241,7 +253,7 @@ public function crop($top = 0, $left = 0, $right = 0, $bottom = 0)
241
253
* @param bool $tile
242
254
* @return void
243
255
* @throws \LogicException
244
- * @throws \Exception
256
+ * @throws \Magento\Framework\ Exception\LocalizedException
245
257
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
246
258
* @SuppressWarnings(PHPMD.NPathComplexity)
247
259
*/
@@ -253,28 +265,12 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
253
265
$ this ->_checkCanProcess ();
254
266
255
267
$ opacity = $ this ->getWatermarkImageOpacity () ? $ this ->getWatermarkImageOpacity () : $ opacity ;
256
-
257
268
$ opacity = (double )number_format ($ opacity / 100 , 1 );
258
- $ watermark = new \Imagick ($ imagePath );
259
269
260
- if ($ this ->getWatermarkWidth () &&
261
- $ this ->getWatermarkHeight () &&
262
- $ this ->getWatermarkPosition () != self ::POSITION_STRETCH
263
- ) {
264
- $ watermark ->resizeImage (
265
- $ this ->getWatermarkWidth (),
266
- $ this ->getWatermarkHeight (),
267
- \Imagick::FILTER_CUBIC ,
268
- self ::BLUR_FACTOR
269
- );
270
- }
270
+ $ watermark = new \Imagick ($ imagePath );
271
271
272
- if (method_exists ($ watermark , 'getImageAlphaChannel ' )) {
273
- // available from imagick 6.4.0
274
- if ($ watermark ->getImageAlphaChannel () == 0 ) {
275
- $ watermark ->setImageAlphaChannel (\Imagick::ALPHACHANNEL_OPAQUE );
276
- }
277
- }
272
+ $ this ->resizeWatermark ($ watermark );
273
+ $ this ->handleWatermarkAlphaChannel ($ watermark );
278
274
279
275
$ compositeChannels = \Imagick::CHANNEL_ALL ;
280
276
$ watermark ->evaluateImage (\Imagick::EVALUATE_MULTIPLY , $ opacity , \Imagick::CHANNEL_OPACITY );
@@ -307,33 +303,16 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
307
303
308
304
try {
309
305
if ($ tile ) {
310
- $ offsetX = $ positionX ;
311
- $ offsetY = $ positionY ;
312
- while ($ offsetY <= $ this ->_imageSrcHeight + $ watermark ->getImageHeight ()) {
313
- while ($ offsetX <= $ this ->_imageSrcWidth + $ watermark ->getImageWidth ()) {
314
- $ this ->_imageHandler ->compositeImage (
315
- $ watermark ,
316
- \Imagick::COMPOSITE_OVER ,
317
- $ offsetX ,
318
- $ offsetY ,
319
- $ compositeChannels
320
- );
321
- $ offsetX += $ watermark ->getImageWidth ();
322
- }
323
- $ offsetX = $ positionX ;
324
- $ offsetY += $ watermark ->getImageHeight ();
325
- }
306
+ $ this ->addTiledWatermark ($ positionX , $ positionY , $ watermark , $ compositeChannels );
326
307
} else {
327
- $ this ->_imageHandler ->compositeImage (
328
- $ watermark ,
329
- \Imagick::COMPOSITE_OVER ,
330
- $ positionX ,
331
- $ positionY ,
332
- $ compositeChannels
333
- );
308
+ $ this ->addSingleWatermark ($ positionX , $ positionY , $ watermark , $ compositeChannels );
334
309
}
335
310
} catch (\ImagickException $ e ) {
336
- throw new \Exception ('Unable to create watermark. ' , $ e ->getCode (), $ e );
311
+ throw new LocalizedException (
312
+ __ ('Unable to create watermark. ' ),
313
+ $ e ,
314
+ $ e ->getCode ()
315
+ );
337
316
}
338
317
339
318
// merge layers
@@ -346,12 +325,14 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
346
325
* Checks required dependencies
347
326
*
348
327
* @return void
349
- * @throws \Exception If some of dependencies are missing
328
+ * @throws \Magento\Framework\ Exception\LocalizedException If some of dependencies are missing
350
329
*/
351
330
public function checkDependencies ()
352
331
{
353
- if (!class_exists ('\Imagick ' , false )) {
354
- throw new \Exception ("Required PHP extension 'Imagick' was not loaded. " );
332
+ if (!class_exists ('Imagick ' , false )) {
333
+ throw new LocalizedException (
334
+ __ ('Required PHP extension \'Imagick \' was not loaded. ' )
335
+ );
355
336
}
356
337
}
357
338
@@ -499,4 +480,86 @@ protected function _getImagickPixelObject($color = null)
499
480
{
500
481
return new \ImagickPixel ($ color );
501
482
}
483
+
484
+ /**
485
+ * Resizes watermark to desired size, when it is not stretched
486
+ *
487
+ * @param \Imagick $watermark
488
+ */
489
+ private function resizeWatermark (\Imagick $ watermark ): void
490
+ {
491
+ if ($ this ->getWatermarkWidth () &&
492
+ $ this ->getWatermarkHeight () &&
493
+ $ this ->getWatermarkPosition () != self ::POSITION_STRETCH
494
+ ) {
495
+ $ watermark ->resizeImage (
496
+ $ this ->getWatermarkWidth (),
497
+ $ this ->getWatermarkHeight (),
498
+ \Imagick::FILTER_CUBIC ,
499
+ self ::BLUR_FACTOR
500
+ );
501
+ }
502
+ }
503
+
504
+ /**
505
+ * Keeps transparenty if watermark is transparent
506
+ *
507
+ * @param \Imagick $watermark
508
+ */
509
+ private function handleWatermarkAlphaChannel (\Imagick $ watermark ): void
510
+ {
511
+ if (method_exists ($ watermark , 'getImageAlphaChannel ' )) {
512
+ // available from imagick 6.4.0
513
+ if ($ watermark ->getImageAlphaChannel () == 0 ) {
514
+ $ watermark ->setImageAlphaChannel (\Imagick::ALPHACHANNEL_OPAQUE );
515
+ }
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Add tiled watermark at starting given X,Y position
521
+ *
522
+ * @param int $positionX
523
+ * @param int $positionY
524
+ * @param \Imagick $watermark
525
+ * @param bool $compositeChannels
526
+ */
527
+ private function addTiledWatermark ($ positionX , $ positionY , \Imagick $ watermark , $ compositeChannels ): void
528
+ {
529
+ $ offsetX = $ positionX ;
530
+ $ offsetY = $ positionY ;
531
+ while ($ offsetY <= $ this ->_imageSrcHeight + $ watermark ->getImageHeight ()) {
532
+ while ($ offsetX <= $ this ->_imageSrcWidth + $ watermark ->getImageWidth ()) {
533
+ $ this ->_imageHandler ->compositeImage (
534
+ $ watermark ,
535
+ \Imagick::COMPOSITE_OVER ,
536
+ $ offsetX ,
537
+ $ offsetY ,
538
+ $ compositeChannels
539
+ );
540
+ $ offsetX += $ watermark ->getImageWidth ();
541
+ }
542
+ $ offsetX = $ positionX ;
543
+ $ offsetY += $ watermark ->getImageHeight ();
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Add watermark at given X,Y position
549
+ *
550
+ * @param int $positionX
551
+ * @param int $positionY
552
+ * @param \Imagick $watermark
553
+ * @param bool $compositeChannels
554
+ */
555
+ private function addSingleWatermark ($ positionX , int $ positionY , \Imagick $ watermark , bool $ compositeChannels ): void
556
+ {
557
+ $ this ->_imageHandler ->compositeImage (
558
+ $ watermark ,
559
+ \Imagick::COMPOSITE_OVER ,
560
+ $ positionX ,
561
+ $ positionY ,
562
+ $ compositeChannels
563
+ );
564
+ }
502
565
}
0 commit comments