Adding an Image Watermark with PHP

posted Tuesday, January 20th 2015 at 8:51 AM by

Create an Image Watermark with PHP

PHP has some pretty neat tools for manipulating images. Using some of those tools, we can add watermarks to images automatically. Lets take a look at the example code.

The PHP Code

//                            //
//                            //

//update the memory limit to allow for really large images
ini_set('memory_limit', '256M');

//return the document as a jpeg, as opposed to html
header('Content-Type: image/jpeg');

//set the file path for the image we want to add a watermark to
$sourceFile = $_SERVER['DOCUMENT_ROOT'] . '/images/pants-the-cat-test-image.jpg';

//load the source image
$sourceImage = imagecreatefromjpeg($sourceFile);
//the next two lines preserve the alpha layer of the image, so we can use transparency with the watermark
imagealphablending($sourceImage, false);
imagesavealpha($sourceImage, true);

//load the watermark image
$watermarkImage = imagecreatefrompng('ak-super-watermark.png');
//the next two lines preserve the alpha layer of the image, so we can use transparency with the watermark
imagealphablending($watermarkImage, false);
imagesavealpha($watermarkImage, true);

//determine the height and width of the source image
$sourceImageWidth = imagesx($sourceImage);
$sourceImageHeight = imagesy($sourceImage);
//determine the height and width of the watermark image
$watermarkImageWidth = imagesx($watermarkImage);
$watermarkImageHeight = imagesy($watermarkImage);

//declare an output image, this is the same size as the source image
$outputImage = imagecreatetruecolor($sourceImageWidth,$sourceImageHeight);
//again, preserve the alpha layer so we can use transparency
imagealphablending($outputImage, false);
imagesavealpha($outputImage, true);

//set the position you want the water mark to start at
//in this case, my water make width extends 100% of the image, so I'll position the X coordinate at 0
$watermarkPositionX = 0;
//as for the Y coordinate, i want it to 'paste' the watermark about 2/3 of the image height, in this case 60% of the image height
$watermarkPositionY = $sourceImageHeight * .60;
$watermarkScaledWidth = $sourceImageWidth;

//since we need to scale the watermark image, we need to determine how big the source image is compared to the watermark image
//find the ratio of the widths, then apply that to the height to determine the correct height scaling for the watermark image
$watermarkScaledHeight = ($watermarkScaledWidth / $watermarkImageWidth) * $watermarkImageHeight;

//next we need to create another image to store the scaled version of the watermark
$watermarkImageScaled = imagecreatetruecolor($watermarkScaledWidth, $watermarkScaledHeight);
//again, preserve the alpha layer
imagealphablending($watermarkImageScaled, false);
imagesavealpha($watermarkImageScaled, true);

//here we use imagecopyresampled() to scale the watermark image to be the same width as the source image
imagecopyresampled( $watermarkImageScaled , $watermarkImage , 0 , 0 , 0 , 0 , $watermarkScaledWidth , $watermarkScaledHeight , $watermarkImageWidth , $watermarkImageHeight );

//next, we use imagecopymerge() to copy the source image to our output
imagecopymerge($outputImage, $sourceImage, 0, 0, 0, 0, $sourceImageWidth, $sourceImageHeight, 100);

//after the source image is pasted to the output, we can finish by copying the scaled watermark on top of the source image
imagecopymerge_alpha($outputImage, $watermarkImageScaled, $watermarkPositionX, $watermarkPositionY, 0, 0, $watermarkScaledWidth, $watermarkScaledHeight, 100);

//return the jpeg image with the watermark
imagejpeg($outputImage, null, 100);

//return the memory limit to normal
ini_set('memory_limit', '64M');

//                                             //
//                                             //

function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct){
    // creating a cut resource
    $cut = imagecreatetruecolor($src_w, $src_h);

    // copying relevant section from background to the cut resource
    imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
    // copying relevant section from watermark to the cut resource
    imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
    // insert cut resource to destination image
    imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
    // free up memory.

Code Breakdown

First, there are two images used. The source image can by any image you want to add the watermark to, and the watermark is the image you want to overlay on top of the source. They're shown below for reference, and the watermark can be positioned anywhere on the image. Just note that the watermark spans the entire width in this example and should be large enough to accommodate the images you want to use — PHP can scale down the watermark, but it will lose quality being scaled up.

The Source Image

The source can be any image you want to use, in this case, its Pants destroying one of her toys.

PHP Watermark Example

The Watermark

This is a PNG image with a transparency set. In this example, what appears to be grey is actually black, set to 35% opacity.

PHP Watermark Example

Putting it all Together

Next, the script doesn't actually create, save, or overwrite the source image. Instead, it returns the outputted image with the watermark via the script alone. This can be used with an .htaccess file to automatically add watermarks to any images you'd like.

The imagecopymerge_alpha() Function

This isn't a standard PHP function, but is needed to copy the watermark image with the alpha layer. The function is included in the code sample above.

The Output

Here is the example image, after its been processed by the script.

PHP Watermark Example

Final Thoughts

As you can see above, the script works to take any source image and overlay the watermark. Hopefully the comments in the code are enough to provide guidance. If you have any questions, let me know in the comments!

Share This:



View (1) Comments Post a Comment
  • Replying to Adam Konieska on Adding an Image Watermark with PHP

  • shanory
    Thursday, April 26th 2018 at 7:14 AM

    How To Get Epiduo Without Prescription Medecin Prescripteur Baclofene Lyon Isotretinoin Find <a href=http://cialicheap.com>generic 5mg cialis best price</a> Ciprofloxacin Online Without A Prescia

    • Replying to ShaNory