<?php
header('Content-type: image/jpeg');

$source = 'a.jpg';
$watermark = imagecreatefrompng('logo.png');
$watermark_width = imagesx($watermark);
$watermark_height = imagesy($watermark);
$image = imagecreatetruecolor($watermark_width,$watermark_height);
$image = imagecreatefromjpeg($source);
$image_size = getimagesize($source);
$x = $image_size[0] - $watermark_width - 10;
$y = $image_size[1] - $watermark_height - 10;
imagecopymerge($image, $watermark, $x, $y, 0, 0, $watermark_width, $watermark_height, 20);
imagejpeg($image);

?>

Dani AI

Generated

Two quick fixes explain why the watermark from 's snippet can be invisible or wrong.

First, the script creates a small truecolor image then immediately overwrites that variable with the JPEG — avoid creating then overwriting the same resource. Second, using imagecopymerge() with a PNG watermark commonly loses the watermark's proper alpha/transparency; imagecopymerge() was not designed to keep PNG alpha intact. (php.net)

To keep PNG transparency you need to work with the GD alpha flags: disable alpha blending when preparing images and enable saving the alpha channel before output. Calling imagealphablending($img, false) and imagesavealpha($img, true) lets PNG alpha survive your operations and final imagepng() output. If you only need a faint watermark, either make the watermark PNG semi‑transparent in an editor, or use a small helper that composites the PNG onto a copy of the destination and then merges that block back with an opacity percentage. (php.net)

Here is a compact helper pattern (adapt and test) that preserves alpha while allowing a merge percentage:

function mergePngWithOpacity($dst, $src, $dst_x, $dst_y, $opacity = 50) {
  $w = imagesx($src); $h = imagesy($src);
  $cut = imagecreatetruecolor($w, $h);
  imagealphablending($cut, false); imagesavealpha($cut, true);
  imagecopy($cut, $dst, 0, 0, $dst_x, $dst_y, $w, $h);
  imagecopy($cut, $src, 0, 0, 0, 0, $w, $h);
  imagecopymerge($dst, $cut, $dst_x, $dst_y, 0, 0, $w, $h, $opacity);
  imagedestroy($cut);
}

Quick checklist before running: confirm GD is installed and imagecreatefrompng/imagecreatefromjpeg exist; verify file paths and permissions; ensure computed $x,$y are >= 0 (use max(0, ...)); call the correct Content-Type for your output and send headers before any output; and free resources with imagedestroy(). For a simple, reliable route, pre-render the watermark at the exact opacity you want (transparent PNG) and use imagecopy() as suggested. (php.net)

Recommended Answers

All 2 Replies

Just use this:

<?php
// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('stamp.png');
$im = imagecreatefromjpeg('photo.jpeg');

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Copy the stamp image onto our photo using the margin offsets and the photo 
// width to calculate positioning of the stamp. 
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));

// Output and free memory
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

src:PHP Manual

& customize as needed to get desired size and positioning...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.