Tips, News and Comments on HTML Guard


May 25th, 2009, by Andreas

Dynamic Image Watermarks with PHP

Introduction

An effective way to protect the images of a web page from being copied or linked from other websites is to visually mark them with a logo, a copyright notice, or any other identifying marker. In this article, I will explain how PHP can be used to quickly and dynamically watermark images on a web server without having to modify the original image files.

Watermark Sample

The following two images provide an example of what an image looks before and after watermarking it with the PHP script:

Original image:
Sample Image: Central Park

Watermarked image:
Watermarked Sample Image: Central Park

As you can see, the watermark is discreetly placed in the lower right corner without inhibiting the viewer from seeing the image.

Download and Installation

Please click here to download the watermarking script (including a sample page and the SVG sources for the watermark image).

To install the script, just upload the “watermark.php” file to your web server and change image tags in your HTML code from something like this:

<img src="sample1.jpg" alt="" />

to this:

<img src="watermark.php?image=sample1.jpg&amp;watermark=watermark.png" alt="" />

Instead of linking an image directly, pass the image’s file name to the PHP script and additionally reference a watermark file. Supported image types are JPEG, PNG, and GIF. Image files can also be placed in subfolders relative to the folder of the script file:

<img src="watermark.php?image=folder/sample1.jpg&amp;watermark=folder/watermark.png" alt="" />

The Code in Detail

First, the script opens both the original image and the watermark image using one of the imagecreatefrom(jpeg/gif/png) functions. Like many other functions used in the script, these functions are provided by the GD library that has been bundled with PHP since version 4.3.

function imagecreatefromfile($image_path) {
  // retrieve the type of the provided image file
  list($width, $height, $image_type) = getimagesize($image_path);
 
  // select the appropriate imagecreatefrom* function based on the determined
  // image type
  switch ($image_type)
  {
    case IMAGETYPE_GIF: return imagecreatefromgif($image_path); break;
    case IMAGETYPE_JPEG: return imagecreatefromjpeg($image_path); break;
    case IMAGETYPE_PNG: return imagecreatefrompng($image_path); break;
    default: return ''; break;
  }
}

Next, the intended position of the watermark in the output image is calculated (the watermark is placed in the lower right corner).

$watermark_pos_x = imagesx($image) - imagesx($watermark) - 8;
$watermark_pos_y = imagesy($image) - imagesy($watermark) - 10;

Now the source image and the watermark are being merged:

imagecopy($image, $watermark,  $watermark_pos_x, $watermark_pos_y, 0, 0,
  imagesx($watermark), imagesy($watermark));

The result is outputted to the browser as a JPEG image with the best quality (100):

header('Content-Type: image/jpeg');
imagejpeg($image, NULL, 100);

Finally, we free the memory allocated for the images:

imagedestroy($image);
imagedestroy($watermark);