Dynamic PHP watermarking with ImageMagick
In one of our previous articles, we covered a very basic technique to add watermark to image using PHP and GD. This technique will add a transparent watermark to target image - disadvantage being that the watermark is a part of the final image "for good". That means, if you need to change the watermark on already watermarked images, you will need the original images to re-watermark them, and that means more disk space used and generally more data to handle.
In this article, we will show how to make a flexible watermarking routine which enables to change the watermark anytime without the need to store both the original and watermarked images (although the watermarked images ARE in fact stored on disk, but only for caching). The watermarking itself will be done using ImageMagick, but it can be done using basic GD too (but that is not covered in this article).
Let's have a folder with the source images "source_images". Then, we have the watermark image, "watermark.png" and the folder to store the watermarked images, "output_images". The routine looks like this:
$photo = $_GET['photo']; $src = 'source_images/'.$photo; $dst = 'output_images/'.$photo; $watermark_image = 'watermark.png'; $create_watermark = false; if(file_exists($dst)) { $t_img = filemtime($dst); $t_wm = filemtime($watermark_image); if($t_wm > $t_img) $create_watermark = true; } if(!file_exists($dst) || $create_watermark) { $cmd = "composite -dissolve 50% -gravity south-east ".$watermark_image." ".$src." ".$dst; exec($cmd); } header("Content-type: image/jpeg"); $f = file_get_contents($dst); echo $f;
Note that this code does not cover security issues - in a production environment, you will have to sanitize the $_GET['photo'] variable in order to disallow access to other folders:
$photo = $_GET['photo']; // Just a very simple and basic protection... $photo = str_replace('..', '', $photo); $photo = str_replace('/', '', $photo); $photo = str_replace('\\', '', $photo);
The routine creates an image with the watermark when needed. The watermark will be placed in the bottom - right corner (the parameter -gravity south-east in the ImageMagick command line), but you can place it anywhere (see documentation). If the image already exists, it is used without needing to re-create the watermark again. But, if the watermark image itself is updated, all images will be updated too when needed.
The routine is to be called like this (let's pretend we saved the source as watermark.php):
<img src="watermark.php?photo=my_image.jpg" />
March 1st, 2010 - 15:51
Nice! A simple and elegant solution to a problem I was researching. Thanks!