...

View Full Version : GD - Overlay Watermark



Velox Letum
11-11-2005, 07:46 PM
This code overlays a watermark (transparent or not) on to an image using the GD image library. This code would be useful for websites that commonly have pictures uploaded to them and wish to overlay a watermark over them, as this code can be called in a url, thus from img tags. Such as image.php?image=uploaded-343223.jpg. The position of the watermark starts from the bottom right corner, and the offset can easily be configured with the $w_offset and $h_offset variables below.


<?php
// Velox Letum (2005)
// elementation@gmail.com

$image = $HTTP_GET_VARS['image']; // Useful if using in an img tag to call images
$image = str_replace(array("/", ".."), "", $image); // Prevent abuse
$overlay = 'overlay.png';
$dir = '../hresources/';

// A default image for the demo...remove if you wish.
if ($image == NULL) {
$image = 'donutland.jpg';
}

// Find if image exists
if (!file_exists($dir . $image)) {
die("Image does not exist.");
}

// Set offset from bottom-right corner
$w_offset = 0;
$h_offset = 0;

$extension = strtolower(substr($image, strrpos($image, ".") + 1));

// Load image from file
switch ($extension)
{
case 'jpg':
$background = imagecreatefromjpeg($dir . $image);
break;
case 'jpeg':
$background = imagecreatefromjpeg($dir . $image);
break;
case 'png':
$background = imagecreatefrompng($dir . $image);
break;
case 'gif':
$background = imagecreatefromgif($dir . $image);
break;
default:
die("Image is of unsupported type.");
}

// Find base image size
$swidth = imagesx($background);
$sheight = imagesy($background);

// Turn on alpha blending
imagealphablending($background, true);

// Create overlay image
$overlay = imagecreatefrompng($dir . $overlay);

// Get the size of overlay
$owidth = imagesx($overlay);
$oheight = imagesy($overlay);

// Overlay watermark
imagecopy($background, $overlay, $swidth - $owidth - $w_offset, $sheight - $oheight - $h_offset, 0, 0, $owidth, $oheight);

// Output header and final image
header("Content-type: image/jpeg");
header("Content-Disposition: filename=" . $image);
imagejpeg($background);

// Destroy the images
imagedestroy($background);
imagedestroy($overlay);

?>

WA
11-12-2005, 01:29 AM
A short description of what this code does and in what setting would really help. :)

Velox Letum
11-12-2005, 01:52 AM
My apologies, I will be sure to include a description and possible use for scripts in which they are not readily apparent.

Mindless
12-20-2005, 12:45 PM
OMG, thank you so much, you have no idea how long I've been search for a tutorial / script that i can use on my site. This has helped me so much! I really appreciate the snippet you have provided.:thumbsup:

trib4lmaniac
12-20-2005, 03:48 PM
Just so you know..

$image = imagecreatefromstring(file_get_contents('path/to/image.jpg'));
..removes the need for nasty switch statements.

missing-score
12-20-2005, 04:03 PM
Just so you know..

$image = imagecreatefromstring(file_get_contents('path/to/image.jpg'));
..removes the need for nasty switch statements.

But also slows down the script (possibly a fair bit based on the image), so I would reccomend going with the switch statement. :)

Velox Letum
12-23-2005, 08:16 PM
OMG, thank you so much, you have no idea how long I've been search for a tutorial / script that i can use on my site. This has helped me so much! I really appreciate the snippet you have provided.:thumbsup:

Glad to help. And that's why I used the switch statements, because imagecreatefromstring() really slowed it all down, especiallly when testing with 2048x1538 pixel images.

Demon Templates
03-10-2007, 03:56 PM
Hi all

I know this was posted a long time ago by Velox Letum but i am after something very similar to this as i require a watermarked image that will overlay the whole page.

Having read the post i do not fully understand what is required to be able to use it and where i would put the folders.

Any advice would be great and of huge benifit to me.

Thanks


Richard

Inigoesdr
03-10-2007, 04:05 PM
Pretty much just PHP, and GD2. You'll probably want to use imagecopyresampled instead of imagecopy. That original script looks like he was keeping the images out of publicly accessible areas and watermarking them on-the-fly as they load in his webpages. That could put a large amount of stress on your server if you have more than a couple of images.

idalatob
09-18-2007, 02:40 PM
Instead of using a extention, cant you use getimagesize? eg.


$params = getimagesize($image) or die("File not found or supported");
switch($params[2]){
//1- gif
//2-jpeg
//3-Png
}

This would also mean that imagesx and imagesy would not have to be invoked as $params[0] and $params[1] would be their equivalents. Also the first check (!file_exists) is also redundant as getimagesize returns false if the selected file isnt a valid image or not found.

Im not sure if Im making any sense? Send me back to the loony bin someone.

Inigoesdr
09-18-2007, 06:19 PM
Yes, you could use getimagesize() instead. :)

simon@vg
10-19-2007, 03:50 PM
Thanks for the tips on this page guys. This version does (should do) the following:

1. Load the image and scale it to a given maximum dimension.
2. Load the watermark file
3. Work out the width of the image and the watermark and apply the watermark centrally
4. Create a thumbnail without a watermark but scaled to a given maximum dimension.
5. Save out both thumbnail and watermarked images to file.
6. Delete the orginal file.

I did it for me and my needs but it should be pretty easy to tweak.
Might help anyone putting up an image library ...



<?php

function waterMarkImage($catalogueRef, $imageName = '') {

$watermarkSrc = dirname(__FILE__) . '/spc_watermark.png';
$sourceDir = dirname(__FILE__) . '/tmp/';
$thumbnailDir = dirname(__FILE__) . '/../images/thumbs/';
$outputDir = dirname(__FILE__) . '/../images/large/';
$maximumDimension = 500; // max image dimension
$maximumThumbnail = 200; // max thumbnail dimension
if ($imageName == '') {
$imageName = $catalogueRef . ".jpg";
}
$rawImage = imagecreatefromjpeg($sourceDir . $imageName);

// ======================================================================== Find base image size & scale down to a max of 500px

$rawWidth = imagesx($rawImage);
$rawHeight = imagesy($rawImage);

$imageScaleTo = 1;


if ($rawWidth >= $rawHeight) { // if a landsscape or square image

if ($rawWidth > $maximumDimension) {
$imageScaleTo = $maximumDimension/$rawWidth;
}

// scale thumbnail
$thumbNailScale = $maximumThumbnail/$rawWidth;
$thumbNailWidth = $maximumThumbnail;
$thumbNailHeight = floor($rawHeight * $thumbNailScale);
$thumbNailImage = imagecreatetruecolor($thumbNailWidth, $thumbNailHeight);
imagecopyresampled($thumbNailImage, $rawImage, 0, 0, 0, 0, $thumbNailWidth, $thumbNailHeight, $rawWidth, $rawHeight);

} else { // if a portrait image

if ($rawHeight > $maximumDimension) {
$imageScaleTo = $maximumDimension/$rawHeight;
}

// scale thumbnail
$thumbNailScale = $maximumThumbnail/$rawHeight;
$thumbNailWidth = floor($rawWidth * $thumbNailScale);
$thumbNailHeight = $maximumThumbnail;
$thumbNailImage = imagecreatetruecolor($thumbNailWidth, $thumbNailHeight);
imagecopyresampled($thumbNailImage, $rawImage, 0, 0, 0, 0, $thumbNailWidth, $thumbNailHeight, $rawWidth, $rawHeight);

}

// ======================================================================== Create Output Image

$outputWidth = floor($rawWidth * $imageScaleTo);
$outputHeight = floor($rawHeight * $imageScaleTo);

$outputImage = Imagecreatetruecolor($outputWidth, $outputHeight);
imagecopyresampled($outputImage, $rawImage, 0, 0, 0, 0, $outputWidth, $outputHeight, $rawWidth, $rawHeight);

// Turn on alpha blending
imagealphablending($outputImage, true);

// Create overlay image
$watermark = imagecreatefrompng($watermarkSrc);

// Get the offset centring for the overlay
$offsetWidth = floor(($outputWidth - imagesx($watermark))/2);
$offsetHeight = floor(($outputHeight - imagesy($watermark))/2);

// Overlay watermark
imagecopy($outputImage, $watermark, $offsetWidth, $offsetHeight, 0, 0, imagesx($watermark), imagesy($watermark));

// Output header and final images to file
imagejpeg($outputImage, $outputDir . $catalogueRef . ".jpg");
imagejpeg($thumbNailImage, $thumbnailDir . $catalogueRef . ".jpg");

// Destroy the images
imagedestroy($outputImage);
imagedestroy($thumbNailImage);
imagedestroy($rawImage);
imagedestroy($watermark);

// clean up temp

unlink($sourceDir . $imageName);

}

?>

felgall
10-19-2007, 10:51 PM
Glad to help. And that's why I used the switch statements, because imagecreatefromstring() really slowed it all down, especiallly when testing with 2048x1538 pixel images.

Any particular reason why you set up separate code for jpg and jpeg rather than placing both labels in front of the same code block.


case 'jpg':
case 'jpeg':
$background = imagecreatefromjpeg($dir . $image);
break;

Velox Letum
11-20-2007, 04:50 AM
Any particular reason why you set up separate code for jpg and jpeg rather than placing both labels in front of the same code block.


case 'jpg':
case 'jpeg':
$background = imagecreatefromjpeg($dir . $image);
break;

I couldn't say. It was so long ago I can hardly remember why I'd done a few things the way I did. :o

Majoracle
11-20-2007, 10:56 PM
For anyone who may want it, here's a way to tile watermark the whole image:

Replace:

// Overlay watermark
imagecopy($background, $overlay, $swidth - $owidth - $w_offset, $sheight - $oheight - $h_offset, 0, 0, $owidth, $oheight);
With:

// Overlay watermark
$x = 0;
$y = 0;
$opacity = 100; // overlay's opacity (in percent)
while ($sheight > $y)
{
imagecopymerge($background, $overlay, $x, $y, 0, 0, $owidth, $oheight, $opacity);

if ($x < $swidth) {
$x = $x + $owidth;
}
else if ($x >= $swidth) {
$x = 0;
$y = $y + $oheight;
}
}

I like imagecopymerge better because you can control the opacity of the overlay. If you still wanna use imagecopy though, just change it, and take out the opacity parameter. If the opacity is 100%, it's identical to imagecopy anyway.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum