Watermark Hotlinks with .htaccess, PHP and ImageMagick
Sat, 05/28/2011 - 02:08 — Sean CarneyContinuing my unintentional series on .htaccess, today's discussion is about watermarking.
Recently I wrote about how to block hotlinked images using .htaccess. This was a popular method in the past, but the advent of RSS readers means that many well-meaning visitors will be viewing my site's images using hotlinks. I would rather not lose my RSS audience, so how can I continue to deliver images to them?
I initially considered white-listing popular RSS readers, but maintaining the list would likely be a challenge in the future. So based on this, I need a way to show my images to everyone but degrade them enough to be annoying to anyone who hotlinks to my images. Hmm... a watermark perhaps.
.htaccess
This approach is similar to the previous one which redirects hotlinks to an error image, but instead of redirecting requests to a static image the server redirects to a script which applies a watermark to the requested image.
The modified .htaccess rule to allow watermarking looks like:
# Watermark hotlinked images
RewriteCond %{REQUEST_FILENAME} .*jpg$|.*gif$|.*png$ [NC]
RewriteCond %{REQUEST_URI} !/backend/(.*) [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !seancarney\.ca [NC]
RewriteCond %{HTTP_REFERER} !google\. [NC]
RewriteCond %{HTTP_REFERER} !search\?q=cache [NC]
RewriteCond %{HTTP_REFERER} !msn\. [NC]
RewriteCond %{HTTP_REFERER} !yahoo\. [NC]
RewriteRule (.*) http://www.seancarney.ca/backend/watermark.php?src=$1 [L]
PHP
As you can see above, the request is now fed into a PHP script called watermark. The watermark script collects the url of the originally requested image, sanitizes the url, and then returns a watermarked image using the ImageMagick library.
The code for watermark.php is as follows:
<?php
// Get the URL parameter
if (isset($_GET['src'])) { $input = $_GET['src']; }
// Sanitize the input
$input = str_replace(" ", "%20", $input);
$search = array("\\", "|", ";", ":", "<", ">", "{", "}", "[", "]", "(", ")", "!", "`", "~");
$input = str_replace($search, "", $input);
// Extract the image extension
$ext = substr($input, strlen($input) - 3, 3);
// Send the correct HTTP header for the image type
switch ($ext) {
case "bmp" : header("Content-type: image/bmp"); break;
case "jpg" : header("Content-type: image/jpeg"); break;
case "gif" : header("Content-type: image/gif"); break;
case "png" : header("Content-type: image/png"); break;
case "tif" : header("Content-type: image/tiff"); break;
}
// Prepare and send the watermarked image
passthru("convert -size 200x100 xc:none -fill grey -gravity NorthWest -draw \"text 10,10 'www.seancarney.ca'\" -gravity SouthEast -draw \"text 5,15 'copyright'\" miff:- | composite -tile - http://www.seancarney.ca/$input $ext:-");
?>
ImageMagick
Lastly I should mention what's happening in ImageMagick.
ImageMagick is a powerful tool for creating and editing images. Here I am creating a 200 by 100 pixel image with 'www.seancarney.ca' in the upper left hand corner and 'copyright' in the lower right hand corner using the convert command. Next the composite command is used to tile the watermark image over the original image.
If you want to customize the watermark further I recommend reading annotating using ImageMagick. This presents a good introduction to the different methods available including using images as watermarks.
...and that's it! Now people viewing hotlinked images will be redirected to the watermarked image while regular visitors will be unaffected.
- 601 reads

Comments
Post new comment