Search code examples
phpwatermark

PHP - Watermark PNG Transparency/Alpha


I know this has been covered PLENTY of times but I keep trying different scripts and modifying the one I have, and I still can't get my PNG-24 watermark.png to be transparent over the top of my parent image.

This is what I have currently:

<?

header('content-type: image/jpeg');

$watermark = imagecreatefrompng('watermark.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);

$image = imagecreatefromjpeg($imageURL);
$image = imagecreatetruecolor($watermark_width, $watermark_height);
$size = getimagesize($imageURL);

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

$dest_x = $size[0] - $watermark_width - 5;
$dest_y = $size[1] - $watermark_height - 5;

imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);

imagejpeg($image);

imagedestroy($image);
imagedestroy($watermark);

?>

I've just read another SO question and one of the answers advised that it won't be transparent if you don't add these two lines:

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

I added them and still not. I tried setting headers and output to PNG instead but still no luck. I loaded the watermark in my browser (raw) and it's definitely transparent but just not on the image. Surely this can't be that difficult? Any ideas what I'm doing wrong?


Solution

  • It's not an issue with the application code, it's with the watermark image (PNG) itself.

    A lot of watermark examples/tutorials say to use a PNG-24 watermark, but according to a blog I've just read, they say that imagecopymerge does not deal with PNG-24 files very well, therefore, use PNG-8 and some special 'Save for Web' settings. I did this and it works fine now.

    Here is the relevant section about PNG types from this blog:

    The watermark image should be in one of the following recommended formats:

    • PNG-8 (recommended)
      Colors: 256 or less
      Transparency: On/Off
    • GIF
      Colors: 256 or less
      Transparency: On/Off
    • JPEG
      Colors: True color
      Transparency: n/a

    The imagecopymerge function does not properly handle the PNG-24 images; it is therefore not recommended.

    If you are using Adobe Photoshop to create watermark images, it is recommended that you use "Save for Web" command with the following settings:

    File Format: PNG-8, non-interlaced
    Color Reduction: Selective, 256 colors
    Dithering: Diffusion, 88%
    Transparency: On, Matte: None
    Transparency Dither: Diffusion Transparency Dither, 100%
    

    And for other's benefits, this is the watermark code I have that works:

    <?
    $masterURL = 'mydomain.com/myImage.jpg';
    
    header('content-type: image/jpeg');
    $watermark = imagecreatefrompng('watermark.png');
    $watermark_width = imagesx($watermark);
    $watermark_height = imagesy($watermark);
    $image = imagecreatetruecolor($watermark_width, $watermark_height);
    $image = imagecreatefromjpeg($masterURL);
    $size = getimagesize($masterURL);
    $dest_x = $size[0] - $watermark_width - 5;
    $dest_y = $size[1] - $watermark_height - 5;
    imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);
    imagejpeg($image);
    imagedestroy($image);
    imagedestroy($watermark);
    ?>
    

    After a bit more reading (this comment on the same article), I found out that you CAN use PNG-24 watermarks but with imagecopy instead of imagecopymerge. You can replace this line:

    imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);
    

    with this one:

    imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);
    

    Using imagecopymerge with PNG-8 watermarks is quite good for 'on-the-fly' watermarking, as the watermark file is tiny. If you do watermarking 'behind-the-scenes', it doesn't really matter about file size and you can get much better quality from the PNG-24 watermark, using imagecopy.

    I hope this helps the confused watermarkers out there.