Hotlinking to someone else images is considered a bad practice. Preventing this from happening to your own images is something you do what to try and do. Not only does it protect your bandwidth from supporting other sites with no benefit you. It goes a small way towards keeping your content on your site.
But just blocking all access to the images can be damaging, we need to be smart about how we do it. For example if someone links to and image of your (as apposed to putting it in there own page) you don't want the link to be broken, but it would also be good if it was clear that the image comes from you and not some other site. Also I like to let the images of my site load if someone uses the Google Cache to open it. Finally I don't mind people linking to the images I have created for the purpose of promoting my site. So I am going to show you how to prevent hotlinking and allow for all these conditions
The easiest was of preventing it is using the .htaccess file (that is right no file name, all file extension) and mod_rewrite, the "Swiss Army Knife of URL manipulation". What it allows you to do is when the server gets a request it can change it to another based on a set of rules. So with out further ado, this is the text (with a few changes) you need to put in your .htaccess file. I will try to explain it after you have seen it.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s?)://([^/]*\.)?yoursite\.com/.* [NC]
RewriteCond %{HTTP_REFERER} !^http(s?)://([^/]*\.)?friendlysite\.com/.* [NC]
RewriteCond %{HTTP_REFERER} !^http(s?)://([^/]*\.)?google\..* [NC]
RewriteCond %{HTTP_REFERER} !.*search\?q=cache.* [NC]
RewriteCond %{REQUEST_URI} !^http(s?)://([^/]*\.)?yoursite\.com/affiliate/.* [NC]
RewriteRule ^(.*)(\.jpg|\.jpeg|\.gif|\.png)$ /image.php?pic=$1$2 [L,R=302,NC]
The first line you see above turns mod_rewrite on so we can start getting down to business. Now have a look at the last line, since that is the next one the server would read when processing the request. This line looks a bit more complex. It tells the server what to match and what to then change the url too should it match. The first part is a regular expressions (a string matching system). If we break it down it can be easily under stood. ^ matches the start of the string. The () group the next part together so it will be stored as a variable $1 so it can be used in the URl we want it changed to. The . matches any character, and the * means it can be repeated any number of times. The next part grouped the brackets matches the file extension. As said earlier the dot matches anything, so it has to be escaped with the \ so it is treated like a normal dot. The | means OR. So it means the file extension can be .jpg or .gif etc. The $ matches the end of the string, so make sure the .gif is no in a file named photo.jpg.html for example. The next part of the rule is what it is changed too. The $1 and $2 get replaced with the matched text from their respective bracketed parts. The L between the [] means last (last of the RewriteRules in this group), and the R=302 causes it to return a 302 code (Moved temporarily). The [NC] means make the match case insensitive (png is the same as PNG).
Before actually preforming the rewrite it then checks all the RewriteCond (that is Rewrite Conditions) that must be met before it should be applied. This time we are checking the url that was used to refer the visitor to this image. The first RewriteCond performs a check against the %{HTTP_REFERER}. This would be either the page the image is in, or the page that links to it. This rule has the ! at the start of the matching sting. It means NOT. ^ matching the start of a string and $ the end, so this will match and empty string. So line lets the image be loaded if the referrer is empty. Sometimes it will be, and then normally when you do want the image to load.
The next two rules check if referrer is from particular site, and lets the image load if it is. It is important that you put the site url here, other wise none of its images will load. You can repeat the line as many times as you like to allow certain site to link to your images, such as maybe other sites you own or a friends site. The first part of this matches both HTTP and HTTPS and also the www. or any other subdomain the site may use.
The next two lines basically lets the Google Cache (and many be other caches) to load the images from your site when the pages are viewed that way. When people view a page in the Google cache I want it looking as good as possible to entice people to click any links I may have on that page. Remove these lines if you feel other wise.
The next link matches the request URI. If the image comes from my affiliate folder I am willing to let the image load, as I do expect something in return, more visitors.
So the link changes the url to image.php?pic=the_hotlinked_to_image.gif. I then use a PHP file much like this one to use the location of the image stored in the pic variable to make a page that both displays the image in a way that makes it clear who the image belongs to.
<?php
$pic = strip_tags( $_GET['pic'] );
if ( ! $pic ) {
echo("<h2>No picture</h2><p>No picture specified.</p>");
} else {
?>
<h2>An Image from YourSite.com</h2>
<p style="text-align:center;">
<img src="<?php echo($pic); ?>" alt="Image From YourSite.com">
</p>
<p style="text-align:center;">
Image from
<a href="http://YourSite.com/">YourSite.com</a>.
</p>
<?php
}
?>
What this does is if someone puts the image in their page, a broken one will be shown. The size of the above page would be so small; it would hardly make any effect on how much bandwidth you use. However if the offending site is putting links in there pages to image, everyone will be able to clearly see who the images belong do, and may even visit your site.