From 2adc3b45dec8f8f2469d1559738867e186a29620 Mon Sep 17 00:00:00 2001 From: Oliver Vogel Date: Sat, 3 Aug 2024 17:04:44 +0200 Subject: [PATCH] Fix blending problem in GD's PngEncoder --- src/Drivers/Gd/Encoders/PngEncoder.php | 30 +++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Drivers/Gd/Encoders/PngEncoder.php b/src/Drivers/Gd/Encoders/PngEncoder.php index 8368b7a6..3e4fdec8 100644 --- a/src/Drivers/Gd/Encoders/PngEncoder.php +++ b/src/Drivers/Gd/Encoders/PngEncoder.php @@ -5,6 +5,7 @@ namespace Intervention\Image\Drivers\Gd\Encoders; use GdImage; +use Intervention\Image\Colors\Rgb\Color; use Intervention\Image\Drivers\Gd\Cloner; use Intervention\Image\EncodedImage; use Intervention\Image\Encoders\PngEncoder as GenericPngEncoder; @@ -49,19 +50,32 @@ private function prepareOutput(ImageInterface $image): GdImage return Cloner::clone($image->core()->native()); } - // get blending color - $blendingColor = $this->driver()->colorProcessor($image->colorspace())->colorToNative( - $this->driver()->handleInput($this->driver()->config()->blendingColor) - ); - // clone output instance $output = Cloner::cloneEmpty($image->core()->native()); + /** + * Decode configured blending color + * + * @var Color + */ + $blendingColor = $this->driver()->handleInput($this->driver()->config()->blendingColor); + + // allocate blending color with slighty different alpha value + // to avoid "overwriting" pixels with the same color in the + // original image with transprency + $blendingIndex = imagecolorallocatealpha( + $output, + $blendingColor->red()->value(), + $blendingColor->green()->value(), + $blendingColor->blue()->value(), + 1, + ); + // fill with blending color - imagefill($output, 0, 0, $blendingColor); + imagefill($output, 0, 0, $blendingIndex); - // set transparency - imagecolortransparent($output, $blendingColor); + // define blending index as transparent + imagecolortransparent($output, $blendingIndex); // copy original into output imagecopy($output, $image->core()->native(), 0, 0, 0, 0, imagesx($output), imagesy($output));