Watermark Images

turt2live 1 Tallied Votes 549 Views Share

Simply enough:

Call the function, get the returned filename.

Function Variables:

$file : The input file (source/background)
$destination : Where you want the new watermarked image to go
$overlay : The overlay image (foreground), this is default set (if not passed in) to "images/watermark.png"
$X : X-Position of overlay (default is 10)
$Y : Y-Position of overlay (default is 10)


The return is the destination file (this allows for dynamic watermarks)

Example Usage:

<img src='<?php echo watermark_image("sample.png", "temp/".time().".png"); ?>'>
madCoder commented: Nice. Bookmarked this for future reference. +5
<?php
function watermark_image($file, $destination, $overlay = "images/watermark.png", $X = 10, $Y = 10){
	$watermark =		imagecreatefrompng($overlay);
	$source = 		getimagesize($file);
	$source_mime = 		$source['mime'];
	$source_x = 		$source['width'];
	$source_y = 		$source['height'];
	
	if($source_mime == "image/png"){
		$image = imagecreatefrompng($file);
	}else if($source_mime == "image/jpeg"){
		$image = imagecreatefromjpeg($file);
	}else if($source_mime == "image/gif"){
		$image = imagecreatefromgif($file);
	}
	
	imagecopy($image, $watermark, $X, $Y, 0, 0, imagesx($watermark), imagesy($watermark));
	imagepng($image, $destination);
	
	return $destination;
}
?>

Dani AI

Generated

Nice, simple starter from — useful as-is, but a few practical gaps cause trouble in real use (missing checks, no alpha handling, always writing PNG, no cleanup). The snippet below is a drop-in, safer upgrade: it validates files, preserves PNG transparency, supports common positions and scaling, chooses output format from the destination extension, and frees resources when done.

<?php
function watermark_image_safe($src, $dest, $overlay = 'images/watermark.png', $position = 'bottom-right', $marginX = 10, $marginY = 10, $scale = 1.0, $jpgQuality = 85) {
    if (!extension_loaded('gd')) return false;
    if (!file_exists($src) || !file_exists($overlay)) return false;

    $s = @getimagesize($src); $w = @getimagesize($overlay);
    if (!$s || !$w) return false;
    $srcW = $s[0]; $srcH = $s[1]; $wmW = $w[0]; $wmH = $w[1];

    switch ($s['mime']) {
        case 'image/png':  $img = imagecreatefrompng($src); break;
        case 'image/jpeg': $img = imagecreatefromjpeg($src); break;
        case 'image/gif':  $img = imagecreatefromgif($src); break;
        default: return false;
    }
    switch ($w['mime']) {
        case 'image/png':  $wm = imagecreatefrompng($overlay); break;
        case 'image/jpeg': $wm = imagecreatefromjpeg($overlay); break;
        case 'image/gif':  $wm = imagecreatefromgif($overlay); break;
        default: imagedestroy($img); return false;
    }

    if ($scale > 0 && $scale != 1.0) {
        $nW = max(1, (int)($wmW * $scale)); $nH = max(1, (int)($wmH * $scale));
        $tmp = imagecreatetruecolor($nW, $nH);
        imagealphablending($tmp, false); imagesavealpha($tmp, true);
        $transparent = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
        imagefilledrectangle($tmp, 0, 0, $nW, $nH, $transparent);
        imagecopyresampled($tmp, $wm, 0,0,0,0, $nW, $nH, $wmW, $wmH);
        imagedestroy($wm); $wm = $tmp; $wmW = $nW; $wmH = $nH;
    }

    switch ($position) {
        case 'top-left':    $x = $marginX; $y = $marginY; break;
        case 'top-right':   $x = $srcW - $wmW - $marginX; $y = $marginY; break;
        case 'bottom-left': $x = $marginX; $y = $srcH - $wmH - $marginY; break;
        case 'center':      $x = (int)(($srcW - $wmW)/2); $y = (int)(($srcH - $wmH)/2); break;
        case 'bottom-right':
        default:            $x = $srcW - $wmW - $marginX; $y = $srcH - $wmH - $marginY; break;
    }

    imagecopy($img, $wm, $x, $y, 0, 0, $wmW, $wmH);

    $ext = strtolower(pathinfo($dest, PATHINFO_EXTENSION));
    if ($ext === 'jpg' || $ext === 'jpeg') {
        imagejpeg($img, $dest, $jpgQuality);
    } elseif ($ext === 'gif') {
        imagegif($img, $dest);
    } else { // default PNG
        imagealphablending($img, false);
        imagesavealpha($img, true);
        imagepng($img, $dest);
    }

    imagedestroy($img); imagedestroy($wm);
    return $dest;
}
?>

Notes and tips: use imagecopy (not imagecopymerge) for PNG watermarks so the stamp’s alpha is preserved; PHP’s GD docs show the same watermark pattern. (php.net)

To keep/transmit PNG transparency you must handle alpha correctly: disable alpha blending and set imagesavealpha(true) before saving, and when resizing a PNG create a truecolor canvas, disable blending, enable save-alpha and fill with a fully transparent color before imagecopyresampled. (php.net)

If you hit problems: confirm GD is installed, watch memory limits for very large images, check file permissions, and always call imagedestroy() after processing. Thanks to for the original starting point and for the follow-up — this version keeps the same simple call style but is safer for production.

turt2live 5 Junior Poster in Training

If you would like a sample: Click

webatz 0 Newbie Poster

zz thank very much
i need it

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.