2

I'm trying to draw a partially transparent PNG image on another image I created in my script, but it behaves really strange. I'm using imagecopymerge because I want to use different opacity values, but when I do this, the output looks like this: enter image description here

There must be some problem when processing the image. the yellow parts aren't even visible in the png file. Everything but the black parts are transparent. I saved the image in photoshop and it looks ok when I just use imagecopy or something.

here are the relevant parts of the script:

$imgLogoBg = file_exists($logoBgImgFile)?imagecreatefrompng($logoBgImgFile):null;

$image = imagecreatetruecolor(imagesx($imgBase), imagesy($imgBase));
imagefill($image, 0,0, imagecolorat($imgBase,0,0));

imagecopymerge( $image, $imgLogoBg,
                0,0,
                0,0, imagesx($imgLogoBg), imagesy($imgLogoBg),50);

imagepng($image);

I can't figure out what the problem is. when I use another image the result is similar.

Jojodmo
  • 23,357
  • 13
  • 65
  • 107
user1563232
  • 361
  • 3
  • 17
  • Maybe [this](https://stackoverflow.com/questions/3355993/phpgd-imagecopymerge-not-retaining-png-transparencies) can help. – Olivier Jul 14 '23 at 06:33

1 Answers1

2

The function imagecopymerge wasn't intended to be used with transparency and has problems to handle transparent layers correctly. At least that's what I found some people saying.

With the following code I succeeded to place the batman logo on a photo whereas the transparency was fully preserved.

Black Batmanlogo on photo of Boston

$outputFormat = 'jpg'; // [jpg | png]

$imgBaseName = './myPhoto.jpg';
$imgBase = imagecreatefromjpeg($imgBaseName);

$logoBgImgFile = './batman-logo.png';
$imgLogoBg = file_exists($logoBgImgFile) ? imagecreatefrompng($logoBgImgFile) : null;

if ($imgBase && $imgLogoBg) {

        imagecopyresampled(
            $image,
            $imgLogoBg,
            0, 0, 0, 0,
            imagesx($image) / 2,
            imagesy($image) / 2,
            imagesx($imgLogoBg),
            imagesy($imgLogoBg)
        );

        if ($outputFormat == 'jpg') {
            // Output as jpeg
            header('Content-type: image/jpeg');
            imagejpeg($image);
        }
        elseif ($outputFormat == 'png') {
            // Output as png
            header('Content-type: image/png');
            imagepng($image);
        }
        
        imagedestroy($imgLogoBg);
        imagedestroy($image);
}

Transparency I could achieve with GD and these images only when I adjusted it in the image itself.

enter image description here

Before I tried to use the function imagecopymerge too, but had the problem that the background in size of the image was gray.
There might be images with special settings where it could work, but it would be a hassle to adjust always the images by themselves.
It might also be possible to leave the images like they are but achieve the target by special settings or steps with gd, I just don't know how those had to look if it's possible at all.

There are also other image libraries Gmagick and ImageMagick but related to the code in the question I focused on GD.

David
  • 5,882
  • 3
  • 33
  • 44