Blog - Watermarking hotlinked images

Technology Watermarking hotlinked images

"Hotlinking" is usually associated with using images from someone's web site without permission and at the same time stealing that person's bandwidth. It sure sounds like and is a bad thing, but the topic doesn't end there. Most hotlinkers have no clue what they are doing, and, in my case, the stolen bandwidth really isn't considerable.

One popular solution is to block all requests to images with an unknown referrer (HTTP_REFERER request header) as described in the Apache URL Rewriting Guide (under "Blocked Inline-Images"). I previously used this method myself, actually serving a lo-fi "DO NOT HOTLINK" image instead of the requested image. It works, but it wasn't quite what I wanted. It's not like most of the hotlinking was stealing heaps of my bandwidth anyway. After a while I stopped. watermarkRecently I re-thought this method to instead automatically serve a "watermarked" image only when hotlinked, in my case adding just a small logo with this site's URL (as seen on the right) in a corner of the image and serving it that way.
I generally dislike watermarking, and I strongly agree with Jason Scott's thoughts on the topic. However I don't care giving a watermarked image to those who don't know better than to hotlink my images, and I think it is only fair since they're using my bandwidth. If viewers like the hotlinked image, they might as well know its source (almost never credited by hotlinkers).

This solution can be put in place by adding a few lines to .htaccess (Apache server), and creating a short PHP script.


RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?chipple\.net/  [NC]
RewriteRule ^(.*\.jpg)$ /hotlink.php?fn=$1 [L]

This translates to "for all JPG images, redirect internally to script /hotlink.php, except if the HTTP_REFERER is empty or starts with or".

Additionally, one can add lines similar to the second one, allowing unobstructed images to be used on other specific sites, or on search services like Google Images. That's what I do.

Next is the script that adds the watermark. You will need to create a small image that will be used as the watermark image. I chose to make it a grayscale image with transparent parts. This example assumes that the watermark image is called hotlink.png and located in the same folder as the script. Also, the $sRoot variable must be set to your site's server root path.


$sFN = $_GET['fn']; // Request filename
// Reject bad request filenames, adjust if needed if (strpos($sFN,'../') !== false || strpos($sFN,'.jpg') === false) { header('Status 403 Forbidden'); exit(); }
$sRoot = "/usr/myaccount/public_html/"; // Server root, ADJUST
// Load requested image if ($img = @imagecreatefromjpeg($sRoot.$sFN)) { // Add watermark to bottom-left corner of image, at 80% opacity if ($imgLogo = @imagecreatefrompng('hotlink.png')) { $iHeight = imagesy($img); $iWidthLogo = imagesx($imgLogo); $iHeightLogo = imagesy($imgLogo); imagecopymerge( $img,$imgLogo, // Destination and source images 0,$iHeight-$iHeightLogo, // Position for logo on destination image 0,0,$iWidthLogo,$iHeightLogo, // Area of logo image to copy 80); // Opacity (1-100) imagedestroy($imgLogo); } } else { header('Status 404 Not Found'); exit(); }
// Output image to browser header('Content-Type: image/jpeg'); imagejpeg($img); imagedestroy($img);

That should be it!

Posted on November 4, 2006 at 11:47 | Tweet |


Comments RSS

I like your elegant and effective solution.

Posted by Jason Scott on November 5, 2006 at 10:51

Wow thanks Jason! I'm glad it gets your approval.

Posted by Patrick on November 5, 2006 at 13:58

Very Cool. A couple of questions.

1. If a user were to save the hotlinked image to disk, would the watermarked be saved as well?
2. Can the script be customized to set the watermark on images of a specific size or larger?
3. If you don't set your domain can you have the watermark appear on all your images on your own site?

I was thinking of watermarking my photos but I don't want to go back and redo all my images so this would be a handy script to use!

Posted by Roy on November 6, 2006 at 04:15

1. yes, 2. 3. it's all possible.
However, the point of my solution is to NOT watermark all your images.

Also, if you really were to watermark all your images, you'd rather use a batch script to add the watermark to all images, instead of doing it on every request.

Posted by Patrick on November 6, 2006 at 10:45

Yeah, I realize that the best way would be a batch script. Do you know of anyway to do this on the server without compromising the current size/quality of the images?

The thought of downloading 6000 images and then running a batch script and then uploading them all again is not very appealing.

Posted by Roy on November 6, 2006 at 11:47

Does this only work for .jpg?
What if another type of image is hot linked other than .jpg?

Posted by Dan H. on December 19, 2006 at 00:24

The above script is for JPEG only but you could easily modify it to work with GIF and PNG with just a few more lines of code. I provided this as a simple example and proof of concept.

Posted by Patrick on December 19, 2006 at 00:33

Are you still using this solution (as of March 27th 2008) ?

The reason I ask is I just tried to hotlink one of your images (purely as a quick test, I wouldn't normally hotlink) and the image displayed just fine (without the '' watermark.)

Posted by potnoodle on March 27, 2008 at 22:32

Yes I still use this, although I do exempt some domains by rule.

You can see one image recently hotlinked here, with its watermark: (2nd image of the entry)

Posted by Patrick on March 27, 2008 at 22:38

I see some years have past since you published this. Anyway this is just what I was looking for, and thanks to you I have just managed to implement it for my site. Thank you!

Posted by Simon on June 9, 2011 at 05:31

Thank you so much! I implemented this for my site today, and you made it quick and easy. (smile)

Posted by Elaine on September 8, 2012 at 09:11

Glad to hear that! :)

Posted by Patrick on September 8, 2012 at 10:35

This is nice, but if you have a LOT of people hotlinking you it might be a good idea to save the image to /hotlinked/ folder the first time they hotlink that image instead of generating it each time and using more CPU than necessary.

Posted by Aleix on December 25, 2012 at 04:16

« Akishima | Back to main page | From Ginza to Tokyo Dome City »