55 */
66namespace Magento \Framework \Image \Adapter ;
77
8+ /**
9+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
10+ */
811class Gd2 extends \Magento \Framework \Image \Adapter \AbstractAdapter
912{
1013 /**
@@ -404,7 +407,7 @@ public function rotate($angle)
404407 */
405408 public function watermark ($ imagePath , $ positionX = 0 , $ positionY = 0 , $ opacity = 30 , $ tile = false )
406409 {
407- list ($ watermarkSrcWidth , $ watermarkSrcHeight , $ watermarkFileType , ) = $ this ->_getImageOptions ($ imagePath );
410+ list ($ watermarkSrcWidth , $ watermarkSrcHeight , $ watermarkFileType ,) = $ this ->_getImageOptions ($ imagePath );
408411 $ this ->_getFileAttributes ();
409412 $ watermark = call_user_func (
410413 $ this ->_getCallback ('create ' , $ watermarkFileType , 'Unsupported watermark image format. ' ),
@@ -465,7 +468,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
465468 } elseif ($ this ->getWatermarkPosition () == self ::POSITION_CENTER ) {
466469 $ positionX = $ this ->_imageSrcWidth / 2 - imagesx ($ watermark ) / 2 ;
467470 $ positionY = $ this ->_imageSrcHeight / 2 - imagesy ($ watermark ) / 2 ;
468- imagecopymerge (
471+ $ this -> copyImageWithAlphaPercentage (
469472 $ this ->_imageHandler ,
470473 $ watermark ,
471474 $ positionX ,
@@ -478,7 +481,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
478481 );
479482 } elseif ($ this ->getWatermarkPosition () == self ::POSITION_TOP_RIGHT ) {
480483 $ positionX = $ this ->_imageSrcWidth - imagesx ($ watermark );
481- imagecopymerge (
484+ $ this -> copyImageWithAlphaPercentage (
482485 $ this ->_imageHandler ,
483486 $ watermark ,
484487 $ positionX ,
@@ -490,7 +493,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
490493 $ this ->getWatermarkImageOpacity ()
491494 );
492495 } elseif ($ this ->getWatermarkPosition () == self ::POSITION_TOP_LEFT ) {
493- imagecopymerge (
496+ $ this -> copyImageWithAlphaPercentage (
494497 $ this ->_imageHandler ,
495498 $ watermark ,
496499 $ positionX ,
@@ -504,7 +507,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
504507 } elseif ($ this ->getWatermarkPosition () == self ::POSITION_BOTTOM_RIGHT ) {
505508 $ positionX = $ this ->_imageSrcWidth - imagesx ($ watermark );
506509 $ positionY = $ this ->_imageSrcHeight - imagesy ($ watermark );
507- imagecopymerge (
510+ $ this -> copyImageWithAlphaPercentage (
508511 $ this ->_imageHandler ,
509512 $ watermark ,
510513 $ positionX ,
@@ -517,7 +520,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
517520 );
518521 } elseif ($ this ->getWatermarkPosition () == self ::POSITION_BOTTOM_LEFT ) {
519522 $ positionY = $ this ->_imageSrcHeight - imagesy ($ watermark );
520- imagecopymerge (
523+ $ this -> copyImageWithAlphaPercentage (
521524 $ this ->_imageHandler ,
522525 $ watermark ,
523526 $ positionX ,
@@ -531,7 +534,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
531534 }
532535
533536 if ($ tile === false && $ merged === false ) {
534- imagecopymerge (
537+ $ this -> copyImageWithAlphaPercentage (
535538 $ this ->_imageHandler ,
536539 $ watermark ,
537540 $ positionX ,
@@ -547,7 +550,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
547550 $ offsetY = $ positionY ;
548551 while ($ offsetY <= $ this ->_imageSrcHeight + imagesy ($ watermark )) {
549552 while ($ offsetX <= $ this ->_imageSrcWidth + imagesx ($ watermark )) {
550- imagecopymerge (
553+ $ this -> copyImageWithAlphaPercentage (
551554 $ this ->_imageHandler ,
552555 $ watermark ,
553556 $ offsetX ,
@@ -778,4 +781,106 @@ protected function _createEmptyImage($width, $height)
778781 $ this ->imageDestroy ();
779782 $ this ->_imageHandler = $ image ;
780783 }
784+
785+ /**
786+ * Copy source image onto destination image with given alpha percentage
787+ *
788+ * @internal The arguments and functionality is the same as imagecopymerge
789+ * but with proper handling of alpha transparency
790+ *
791+ * @param resource $destinationImage
792+ * @param resource $sourceImage
793+ * @param int $destinationX
794+ * @param int $destinationY
795+ * @param int $sourceX
796+ * @param int $sourceY
797+ * @param int $sourceWidth
798+ * @param int $sourceHeight
799+ * @param int $alphaPercentage
800+ *
801+ * @return bool
802+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
803+ * @SuppressWarnings(PHPMD.NPathComplexity)
804+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
805+ */
806+ private function copyImageWithAlphaPercentage (
807+ $ destinationImage ,
808+ $ sourceImage ,
809+ $ destinationX ,
810+ $ destinationY ,
811+ $ sourceX ,
812+ $ sourceY ,
813+ $ sourceWidth ,
814+ $ sourceHeight ,
815+ $ alphaPercentage
816+ ) {
817+ if (imageistruecolor ($ destinationImage ) === false || imageistruecolor ($ sourceImage ) === false ) {
818+ return imagecopymerge (
819+ $ destinationImage ,
820+ $ sourceImage ,
821+ $ destinationX ,
822+ $ destinationY ,
823+ $ sourceX ,
824+ $ sourceY ,
825+ $ sourceWidth ,
826+ $ sourceHeight ,
827+ $ alphaPercentage
828+ );
829+ }
830+
831+ if ($ alphaPercentage >= 100 ) {
832+ return imagecopy (
833+ $ destinationImage ,
834+ $ sourceImage ,
835+ $ destinationX ,
836+ $ destinationY ,
837+ $ sourceX ,
838+ $ sourceY ,
839+ $ sourceWidth ,
840+ $ sourceHeight
841+ );
842+ }
843+
844+ if ($ alphaPercentage < 0 ) {
845+ return false ;
846+ }
847+
848+ $ sizeX = imagesx ($ sourceImage );
849+ $ sizeY = imagesy ($ sourceImage );
850+ if ($ sizeX === false || $ sizeY === false || $ sizeX === 0 || $ sizeY === 0 ) {
851+ return false ;
852+ }
853+
854+ $ tmpImg = imagecreatetruecolor ($ sourceWidth , $ sourceHeight );
855+ if ($ tmpImg === false ) {
856+ return false ;
857+ }
858+
859+ if (imagealphablending ($ tmpImg , false ) === false ) {
860+ return false ;
861+ }
862+
863+ if (imagecopy ($ tmpImg , $ sourceImage , 0 , 0 , 0 , 0 , $ sizeX , $ sizeY ) === false ) {
864+ return false ;
865+ }
866+
867+ $ transparency = 127 - (($ alphaPercentage *127 )/100 );
868+ if (imagefilter ($ tmpImg , IMG_FILTER_COLORIZE , 0 , 0 , 0 , $ transparency ) === false ) {
869+ return false ;
870+ }
871+
872+ $ result = imagecopy (
873+ $ destinationImage ,
874+ $ tmpImg ,
875+ $ destinationX ,
876+ $ destinationY ,
877+ $ sourceX ,
878+ $ sourceY ,
879+ $ sourceWidth ,
880+ $ sourceHeight
881+ );
882+ imagedestroy ($ tmpImg );
883+
884+ return $ result ;
885+ }
781886}
0 commit comments