SpongeBobPHPPants SpongeBobPHPPants - 1 year ago 104
PHP Question

Partial black background when watermarking PNG image with GD PHP

I have pieced together a PHP class to perform various image related functions using GD functions of PHP.

It works great for all image types. Rotate, flip, resize, crop and to a lesser extent, watermark.

All but the latter work perfectly. For example after a few changes, rotated PNG images retained their transparency whereas before they were losing that and the background turning black. Common problem, it appears. But all working now.

Where I'm still getting stuck is watermarking a PNG image with another PNG image. It appears to work fine with JPG and other images. This is the code (simplified):

public function writeWatermarkSimple()
$watermarkFile = 'watermark.png';
$watermarkImage = imagecreatefrompng($watermarkFile);

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

$imageFile = 'image.png';
$baseImage = imagecreatefrompng($imageFile);

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

$marginH = imagesx($baseImage) - imagesx($watermarkImage);
$marginV = imagesy($baseImage) - imagesy($watermarkImage);

$cut = imagecreatetruecolor(imagesx($watermarkImage), imagesy($watermarkImage));
imagecopy($cut, $baseImage, 0, 0, $marginH, $marginV, imagesx($watermarkImage), imagesy($watermarkImage));
imagecopy($cut, $watermarkImage, 0, 0, 0, 0, imagesx($watermarkImage), imagesy($watermarkImage));

imagecopymerge($baseImage, $cut, $marginH, $marginV, 0, 0, imagesx($watermarkImage), imagesy($watermarkImage), 80);

if (!imagepng($baseImage, 'watermarked_image.png'))
return false;

return true;

This has been pieced together with various guides and advice people have given based on a similar issue. Again, working perfectly with JPG images and PNG watermarks, but not PNG & PNG.

Some example images:

http://i.imgur.com/hHRWinj.png - This is the watermark I'm using.
http://i.imgur.com/6sy8Ncs.png - This is the image I'm applying the watermark to.
http://i.imgur.com/ghovYLm.png - This is the end result.

The bit I find interesting is that any part of the watermark that is overlaid on a non-transparent portion of the image is working fine. Just the rest of it has the black background.

This leads me to believe I'm close, and I hope that the expertise of you fine people may lead me to the solution.

Thanks ever so for reading.

Answer Source

So, I'm not giving up on finding the correct answer to do this using GD. However, I was overjoyed to find that what needed up to 30 lines of code with GD can be achieved using much less with ImageMagick:

    $image = new Imagick();

    $watermark = new Imagick();
    $watermark->evaluateImage(Imagick::EVALUATE_DIVIDE, 2, Imagick::CHANNEL_ALPHA);

    $image->compositeImage($watermark, imagick::COMPOSITE_OVER, $marginH, $marginV);

So this is before (with GD): http://i.imgur.com/AlS0TcO.png

And after (with ImageMagick and the code above): http://i.imgur.com/zBxlC3R.png

If anyone has an answer that is purely GD then I'd be immensely grateful.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download