PHP: Adding opacity with imagefilter() blackens already transparent areas

424 views Asked by At

I'm currently writing a script to add watermarks to images. Said watermarks vary in their opacity. For example, the base watermark image is a PNG with a fully visible text and a transparent background. When added, I want to fade this base PNG to fit my needs and to make an opaque watermark.

To do that, I use imagefilter() to fade the PNG:

$opacity = 0.25;
$watermarkRes = imagecreatefrompng($filename);

imagealphablending($watermarkRes, false);
imagesavealpha($watermarkRes, true);

$transparency = 1 - $opacity;
imagefilter(
    $watermarkRes, 
    IMG_FILTER_COLORIZE, 
    0,
    0,
    0,
    127*$transparency
);
imagepng($watermarkRes, $filename);

All non-transparent areas get faded nicely, but the existing transarent areas get blackened.

This is the result of the above code:

https://preview.ibb.co/j8zePF/TEST.png

Used as a watermark it looks like this:

https://preview.ibb.co/mLvKPF/15027295625991d55a1ef081_42502547.jpg

While the desired result should be this:

https://preview.ibb.co/f81R4F/TEST_15027295625991d55a1ef081_42502547.jpg

How can I achieve to add opacity to the text while maintaining the transparent areas as they are?

1

There are 1 answers

0
StoryTeller On

Nevermind. The issue was not the function itself, but the fact that I resized the height of the watermark according to its use beforehand.

I removed this code to resize the watermark:

$new_image = imagecreatetruecolor($width, $height);
imagecopyresampled($new_image, $watermarkRes, 0, 0, 0, 0, $width, $height, imagesx($watermarkRes), imagesy($watermarkRes));
$watermarkRes = $new_image;

And instead used the resize code of Dycey provided in the answer to this question:

How do I resize pngs with transparency in PHP?

For my case I created this function to resize images:

/**
 * @param int $width
 * @param int $height
 */
public function resize($width, $height)
{
    $new_image = imagecreatetruecolor($width, $height);

    if($this->image_type === IMAGETYPE_PNG || $this->image_type === IMAGETYPE_GIF) {
        imagealphablending($new_image, false);
        imagesavealpha($new_image,true);
        $transparent = imagecolorallocatealpha(
            $new_image, 255, 255, 255, 127
        );
        imagefilledrectangle(
            $new_image, 0, 0, $width, $height, $transparent
        );
    }

    imagecopyresampled(
        $new_image,
        $this->image,
        0, 0, 0, 0,
        $width, $height,
        imagesx($this->image), imagesy($this->image)
    );
    $this->image = $new_image;
}