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?
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/aThe 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.