TheCarver
TheCarver

Reputation: 19703

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?

Upvotes: 5

Views: 19786

Answers (1)

TheCarver
TheCarver

Reputation: 19703

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.

Upvotes: 17

Related Questions