Skip to content

Commit 92f24ec

Browse files
committed
Handle transparncy correctly for watermark
The watermark functionality uses imagecopymerge for copying the watermark into the image, this function loses the alpha information. Therefor use imagecopy for 100% opacity and use imagefilter in other cases. Resolves: #10661
1 parent 0c0393d commit 92f24ec

File tree

1 file changed

+72
-8
lines changed
  • lib/internal/Magento/Framework/Image/Adapter

1 file changed

+72
-8
lines changed

lib/internal/Magento/Framework/Image/Adapter/Gd2.php

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ public function rotate($angle)
404404
*/
405405
public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity = 30, $tile = false)
406406
{
407-
list($watermarkSrcWidth, $watermarkSrcHeight, $watermarkFileType, ) = $this->_getImageOptions($imagePath);
407+
list($watermarkSrcWidth, $watermarkSrcHeight, $watermarkFileType,) = $this->_getImageOptions($imagePath);
408408
$this->_getFileAttributes();
409409
$watermark = call_user_func(
410410
$this->_getCallback('create', $watermarkFileType, 'Unsupported watermark image format.'),
@@ -465,7 +465,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
465465
} elseif ($this->getWatermarkPosition() == self::POSITION_CENTER) {
466466
$positionX = $this->_imageSrcWidth / 2 - imagesx($watermark) / 2;
467467
$positionY = $this->_imageSrcHeight / 2 - imagesy($watermark) / 2;
468-
imagecopymerge(
468+
$this->imagecopymergeWithAlphaFix(
469469
$this->_imageHandler,
470470
$watermark,
471471
$positionX,
@@ -478,7 +478,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
478478
);
479479
} elseif ($this->getWatermarkPosition() == self::POSITION_TOP_RIGHT) {
480480
$positionX = $this->_imageSrcWidth - imagesx($watermark);
481-
imagecopymerge(
481+
$this->imagecopymergeWithAlphaFix(
482482
$this->_imageHandler,
483483
$watermark,
484484
$positionX,
@@ -490,7 +490,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
490490
$this->getWatermarkImageOpacity()
491491
);
492492
} elseif ($this->getWatermarkPosition() == self::POSITION_TOP_LEFT) {
493-
imagecopymerge(
493+
$this->imagecopymergeWithAlphaFix(
494494
$this->_imageHandler,
495495
$watermark,
496496
$positionX,
@@ -504,7 +504,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
504504
} elseif ($this->getWatermarkPosition() == self::POSITION_BOTTOM_RIGHT) {
505505
$positionX = $this->_imageSrcWidth - imagesx($watermark);
506506
$positionY = $this->_imageSrcHeight - imagesy($watermark);
507-
imagecopymerge(
507+
$this->imagecopymergeWithAlphaFix(
508508
$this->_imageHandler,
509509
$watermark,
510510
$positionX,
@@ -517,7 +517,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
517517
);
518518
} elseif ($this->getWatermarkPosition() == self::POSITION_BOTTOM_LEFT) {
519519
$positionY = $this->_imageSrcHeight - imagesy($watermark);
520-
imagecopymerge(
520+
$this->imagecopymergeWithAlphaFix(
521521
$this->_imageHandler,
522522
$watermark,
523523
$positionX,
@@ -531,7 +531,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
531531
}
532532

533533
if ($tile === false && $merged === false) {
534-
imagecopymerge(
534+
$this->imagecopymergeWithAlphaFix(
535535
$this->_imageHandler,
536536
$watermark,
537537
$positionX,
@@ -547,7 +547,7 @@ public function watermark($imagePath, $positionX = 0, $positionY = 0, $opacity =
547547
$offsetY = $positionY;
548548
while ($offsetY <= $this->_imageSrcHeight + imagesy($watermark)) {
549549
while ($offsetX <= $this->_imageSrcWidth + imagesx($watermark)) {
550-
imagecopymerge(
550+
$this->imagecopymergeWithAlphaFix(
551551
$this->_imageHandler,
552552
$watermark,
553553
$offsetX,
@@ -778,4 +778,68 @@ protected function _createEmptyImage($width, $height)
778778
$this->imageDestroy();
779779
$this->_imageHandler = $image;
780780
}
781+
782+
/**
783+
* Fix an issue with the usage of imagecopymerge where the alpha channel is lost
784+
*
785+
* @param resource $dst_im
786+
* @param resource $src_im
787+
* @param int $dst_x
788+
* @param int $dst_y
789+
* @param int $src_x
790+
* @param int $src_y
791+
* @param int $src_w
792+
* @param int $src_h
793+
* @param int $pct
794+
*
795+
* @return bool
796+
*/
797+
private function imagecopymergeWithAlphaFix(
798+
$dst_im,
799+
$src_im,
800+
$dst_x,
801+
$dst_y,
802+
$src_x,
803+
$src_y,
804+
$src_w,
805+
$src_h,
806+
$pct
807+
) {
808+
if ($pct >= 100) {
809+
return imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
810+
}
811+
812+
if ($pct < 0) {
813+
return false;
814+
}
815+
816+
$sizeX = imagesx($src_im);
817+
$sizeY = imagesy($src_im);
818+
if (false === $sizeX || false === $sizeY) {
819+
return false;
820+
}
821+
822+
$tmpImg = imagecreatetruecolor($src_w, $src_h);
823+
if (false === $tmpImg) {
824+
return false;
825+
}
826+
827+
if (false === imagealphablending($tmpImg, false)) {
828+
return false;
829+
}
830+
831+
if (false === imagecopy($tmpImg, $src_im, 0, 0, 0, 0, $sizeX, $sizeY)) {
832+
return false;
833+
}
834+
835+
$transparancy = 127 - (($pct*127)/100);
836+
if (false === imagefilter($tmpImg, IMG_FILTER_COLORIZE, 0, 0, 0, $transparancy)) {
837+
return false;
838+
}
839+
840+
$result = imagecopy($dst_im, $tmpImg, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
841+
imagedestroy($tmpImg);
842+
843+
return $result;
844+
}
781845
}

0 commit comments

Comments
 (0)