Once upon a time, grayscale image has to be manually converted in order to be displayed on the web. Now with HTML5 canvas, images can be manipulated into grayscale without having to use image editing software. I've put together a demo to show you how to use HTML5 & jQuery to dynamically clone color images into grayscale (see demo). Credits: thanks to Darcy Clarke (my Themify's partner) for the jQuery and Javascript code.
The Purpose
This demo is intented to show you how to make a grayscale/color image hover effect with HTML5 and jQuery. To achieve this effect before HTML5, two images are required: a color and a grayscale version. Now HTML 5 made it easier and faster because the grayscale image is generated from the original source. I hope you will find this script useful in your design such as portfolio showcase, photo gallery, etc.
jQuery Code
The jQuery code below will look for the target images and generate a grayscale version. When hovering the image, it will fade the grayscale image into color.
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
// On window load. This waits until images have loaded which is essential
$(window).load(function(){
// Fade in images so there isn't a color "pop" document load and then on window load
$(".item img").fadeIn(500);
// clone image
$('.item img').each(function(){
var el = $(this);
el.css({"position":"absolute"}).wrap("<div class='img_wrapper' style='display: inline-block'>").clone().addClass('img_grayscale').css({"position":"absolute","z-index":"998","opacity":"0"}).insertBefore(el).queue(function(){
var el = $(this);
el.parent().css({"width":this.width,"height":this.height});
el.dequeue();
});
this.src = grayscale(this.src);
});
// Fade image
$('.item img').mouseover(function(){
$(this).parent().find('img:first').stop().animate({opacity:1}, 1000);
})
$('.img_grayscale').mouseout(function(){
$(this).stop().animate({opacity:0}, 1000);
});
});
// Grayscale w canvas method
function grayscale(src){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var imgObj = new Image();
imgObj.src = src;
canvas.width = imgObj.width;
canvas.height = imgObj.height;
ctx.drawImage(imgObj, 0, 0);
var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
for(var y = 0; y < imgPixels.height; y++){
for(var x = 0; x < imgPixels.width; x++){
var i = (y * 4) * imgPixels.width + x * 4;
var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
imgPixels.data[i] = avg;
imgPixels.data[i + 1] = avg;
imgPixels.data[i + 2] = avg;
}
}
ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return canvas.toDataURL();
}
</script>
How to use it
To apply this to your site:
- include a copy of jquery.js
- paste the code as shown above
- set the target image (eg:
.post-img,img,.gallery img, etc.) - you may change the animation speed (ie. 1000 = 1 second)

Compatibility
It works with any browser that support HTML5 and Javascript such as Chrome, Safari, and Firefox. If HTML5 is not supported, it will fallback to original color image. Note: if it doesn't work with Firefox and Chrome locally. You need to put the HTML file on a web server.
Credits
The Javascript & HTML 5 grayscale is coded by Darcy Clarke.

There is a filter for IE that makes grayscale:
function grayscaleImageIE(imgObj)
{
imgObj.style.filter = ‘progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)’;
}
maybe someone knows how to implement it…
sweet. i just recently came across this photo site: http://olivermuc.com and wondered how that effect was done.
thanks for the insight and code!
m.
Errm, where’s the HTML5? The demo preview is xhtml strict?
It’s cool in theory, but seems far too processor intensive to be feasible. Doing a sprite is going to be faster all around with, of course, the exception of generation time. If you want to automate this process, you could use a server side script to generate and cache a color/bw sprite for you.
HTML is the solution to all browser incompatibility. CSS3 is another great work. All browser should standardize in order to have a better surfing experience.
I think good work! This effect is simple and it easy to do.
Also entirely possible in SVG http://weblogs.mozillazine.org/roc/archives/2008/06/applying_svg_ef.html
I coded kind of a similar effect with the GD library some PHP and jQuery.
http://ibl.ch/agentur/team
The website is coded for WordPress, so there was no ability to use sprites. ‘Cause each team member is displayed by the post_thumbnail function of WordPress.
Maybe your effect is a bit faster than mine.
http://jsdo.it/kiyoken/hoverColor
Please see also this page
While very cool, in this day and age of increased efficiency and faster production, I think it might be quicker to do the three clicks in photoshop to save a greyscale version rather than code all this.
I’m not sure what the load-difference would be for the average user. If the code takes less time to process than loading a new image, that might provide some benefit.
Sorry but I don’t get where the HTML 5 link comes in? HTML 5 is not a requirement for this to work – the demo proves that since its using xHTML 4.1.
@Matt Hackmann – maybe you could include some delayed loading so the filters are applied to the images as they need to be, based on the user scrolling, to improve the performance?
Looks nice!
However wouldn’t it be good to make the grayscale images in Photoshop or another graphic programme because it gives you much more control over how the grayscale image looks.
Of course great for simple images! :-)
Check out this site! i find it very useful. Go ahead ahead and put the link bellow that i provided into your address bar.
Websiteideadrop (dot) zzl (dot) org/
Here you can learn webaite ideas that other users have posted, and share your own ideas. No signups, no registrations, no fees! 900% free!
Help please I add all the things you specified above but the hover effect is still not working. This is the url: http://whitemagicdemo.blogspot.com/.
Does this effect work only for folder images on any server or direct links also
Awful lot of work for a simple thing done in CSS. Looks like another “throw jQuery at every problem” solution.
With IE i get an error for
function grayscale(src){var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
No hover when viewing on an iPad.
宝宝支持你的博客!www.zloli.com 淘宝女装返利,淘宝减肥产品返利
Looks awesome, nice effect
宝宝返利 站长支持你的博客!www.zloli.com 淘宝返利 减肥产品返利。