How to Keep People from Stealing Your Images
Right Click Scripts
You may have many reasons for not wanting people to save your images to their hard drive. There is no fix-all to this problem since you are going to want people to view your images. If someone can view an image, they can always take a screen shot of your page and crop the image out if you do everything possible to keep them from getting the image on their hard drive. That said, there are ways to make it more difficult to save your images off your pages. One such way is to use a no-click script. The script is designed to trap a right click in the browser window and not allow the full click that returns a shortcut menu:
//optional message for click
var message='';
function clicks(e) {
if (e == undefined){
if(event){
if(event.button == 2 || event.button == 0){
if(message)alert(message);
return false;
}
else return true;
}
return true;
}
else {
if(e.which == 3 || e.which == 19){
if(message)alert(message);
return false;
}
return true;
}
}
if(document.layers){
document.captureEvents(Event.MOUSEDOWN);
document.onMouseDown=clicks;
}
document.oncontextmenu = clicks;
document.onmousedown = clicks;
This code should work in IE4+. I say should because I don't have IE4 to test it but the code should be right for IE4+. but I know it works in IE6+ and NN4+(except NN6). Apparently, Netscape wanted to create a following with picture snatchers so they route the context menu event through the browser before giving the event to the window... go figure that out. They must have figured later that they didn't want that following so they fixed it in NN7. It could perhaps be a bug in NN6, but I don't ever recall Netscape having bugs before :)
Feel free to use this right click script if you really want to, but I wouldn't advise it. Blocking the right click is riddled with problems as outlined in the next section. I won't even mention the fact that if you implement this script, it just begs your visitors to figure out what you are trying to hide.
Disguising Images
Using the right click script above is a great quick-fix to prevent image theft, but the most novice of hackers will still be able to get at your images. Not only that, but some people use the right mouse button to navigate, print out a page, or to open a page in a new window, just to name a few. You can already see how irritating this can be to your visitors. Creating an environment on your site that thwarts the functionality of a visitor's browser is generally not a good idea. After all, you most likely want your visitors to return, right?
Here is a solution that I have come up with that is a bit less intrusive on your visitor's and is quite confusing to people who are trying to save your images to their hard drive. I'll give you the basic idea here and you can build upon it to suit your needs.
First off, you will need to be using CSS to pull this off effectively. Make a div, span, or whatever type of HTML element you wish to use. This is going to become your image. You can even use a img tag just like you were going to be inserting a regular image into page. Give the element an id with a name you want to use for your image. In your style sheet, give this element a width and height the same as the image you are trying to disguise and then assign the image you are trying to disguise to the background of the element.
HTML element in your page:
<div id="imgSofaBrown">
</div>
Style declaration in your style sheet:
#imgSofaBrown{width:200px; height:150px; background:url('images/brownsofa.jpg') no-repeat top left;}
Now here's how you are going to disguise your image. Stick a 1pixel wide by 1pixel high transparent gif image inside your HTML element and assign it a height and width to match the image you want to hide:
<div id="imgSofaBrown">
<img src="images/onePxTransparent.gif" width="200px" height="150px">
</div>
And there you have it, a hidden image. Your background image shows right through the transparent image covering the "real image". Now when someone right clicks and saves the image, they will be saving the transparent gif on top so they will have saved a blank image. To make this even more effective, make a bunch of transparent gifs and name them very similar to the actual images you are hiding so when they go to save the picture, the name of the transparent gif will be more disguised in the save as dialog box. In the above example, the dialog box will prompt:
File Name:
If you name the transparent pixel say, brownSofaT.gif, then when someone clicks to save the picture, the resulting dialog box will prompt:
File Name:
To further enhance the effectiveness of this trick, put your element background declaration in an external style sheet and link the style sheet in to your document. Then when the perp tries to view the source code to see what you've done, they won't see the actual paths to the "real" images staring at them in the head of the document. If you add some text to the element as well you can even further disguise what you have done.
If you don't want to wrap up your images in element tags, you can directly assign the "real image" to the transparent image's background like so:
img element in your page:
<img id="imgSofaBrown" src="images/onePxTransparent.gif">
Style declaration in your style sheet:
#imgSofaBrown{width:200px; height:150px; background:url('images/brownsofa.jpg') no-repeat top left;}
You could put the width and height attributes in the img tag instead, it makes no difference. It is probably more effective to do it that way, but I have shown it this way so you can see the possibilities.
You can still float your images just like before, just use your float declaration in your div or span instead of your image. If you are putting the image in the background of a transparent image as described immediately above, float that image just as you normally would.
Here is an example of the style declaration using a separate div with a background and inserting the transparent gif into the div and floating the image to the left:
#imgSofaBrown{float:left;width:200px; height:150px; background:url('images/brownsofa.jpg') no-repeat top left;}
The div or span can be nested inside another structural element just like you would normally insert an image. Alternatively, you could create a separate class with only a float:left; or float:right declaration and assign that class to your div, span, or img along with the specific id. You can have both a class and id for any element, but the declarations in the id will override any declarations in the class.
Be careful when using this technique inline with some text. If you have an image inserted within a paragraph for whatever reason, use span tags or use images and set the image background.
Bonus: You can snicker to yourself every day because you know some idiot is going to be running around your site clicking and saving all your images without checking to see if they even got them. When they do go to look at them, they will see nothing but blank images, ha ha ha.
Preventing Hotlinking
If you are having problems with people hotlinking to your images and eating up your bandwidth, that sucks. Unfortunately, there is no way to stop some people from doing it. An offender can always throw a spoofed header at the site and get the image, even if the site has taken every measure to prevent hotlinking.
What you can do is keep them guessing. Dynamically write your images and use an include file specifying your image directory and change the name of the directory every so often. They can't get it if they don't know where it is right? It isn't all that effective to use javascript since javascript files are too easy to parse. The offending site will just parse your javascript file to find the directory. Your best bet is to use PHP or a similar scripting language and use a line of code like this:
PHP code in the include file (imageDir.php)
$imageDirectory = 'http://www.yourwebsite.com/images/hiddenDirectoryOfTheWeek/';
and writing the image in your page
<img src="<?php print $imageDirectory ?>somePic.jpg">
Of course you will need to include the imageDir.php file in your page.
If you have cPanel for your control panel, you can prevent hotlinking by using the HotLink Prevention under site management. Again, this is only going to keep out the people who don't know what they are doing and those people probably aren't the ones eating up all your bandwidth. This just uses .htaccess files.
I was originally going to give all the code to write the .htaccess file to prevent hotlinks, but that's more .htaccess specific, so I'll put the code there when I get that page done. Part of the problem with .htaccess though is the same thing that makes it work, the referrer field. First off, requests for images generally come from a visitor's computer, not the web server. When the browser dissects the contents of the web page and sees an <img> tag, it sends a request to the appropriate server that serves the image. The browser sends the referrer field with the request. If the user types in your home page, for example, into their address bar, there will be no referrer. Similarly, if the user has the "send referrer" field turned off in their browser, there will be no referrer field in the header of the request either.
So what this means is that you will have to serve the image if there is no referrer present in the request. Users surfing an offending site under these conditions will get your images served to them as well. If this problem could be avoided all together, an offending web site could simply route all external image calls through their server and set the referrer field to your domain or better yet to empty, problem still not solved.
If that wasn't bad enough, using .htaccess to prevent hotlinking will give your server a noticeable performance hit which translates to even slower page loads.
Additionally, you can only use .htaccess on an Apache server and chances are that the server hasn't been set up correctly to use the mod_rewrite module anyway.
Using a .htaccess approach can certainly be effective at keeping novice webmasters and avatar stealers from using your images, but when it comes to keeping the people who know what they are doing from hotlinking your images, you will need to take a more proactive approach. These are the people who will cost you money in bandwidth. This is why I advocate confusing the offenders and making finding your images difficult enough that they will give up on your site and go steal from someone else's site.
