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.

View Demo HTML5 Grayscale

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.

demo screenshot

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)

code screenshot

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.

279 Comments

1 10 11 12
  1. Lala
    Aug 6, 2012 @ 5:53 am

    Keh tak berjaya sik.

    Reply

  2. Kara
    Aug 9, 2012 @ 9:33 pm

    It isn’t working for me :( help??

    Reply

  3. KimPixel
    Aug 10, 2012 @ 10:43 am

    Nice work..

    I modify your script to calculate my dualtone images:
    function duotone(src, newR, newG, newB){
    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*(255-newR))/255)+newR;
    imgPixels.data[i + 1] = ((avg*(255-newG))/255)+newG;
    imgPixels.data[i + 2] = ((avg*(255-newB))/255)+newB;
    }
    }
    ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
    return canvas.toDataURL();
    }

    Reply

  4. 搜索
    Aug 14, 2012 @ 4:57 am

    dfdfd

    Reply

  5. sophia
    Aug 20, 2012 @ 11:26 pm

    where am i suppose to put this? like under what i am so confused :O please help!!

    Reply

  6. Linda
    Aug 27, 2012 @ 1:56 pm

    Is it possible to make this work on tumblr?

    Reply

  7. Redwan
    Aug 29, 2012 @ 4:15 am

    Hi I’m trying to use this code for my tumblr? I’ve tried to put this code in a lot of areas in custom HTML but none of them seem to work? What should be my target image and where in the HTML do I paste the code??? Help?!?

    Reply

  8. QROPS
    Sep 13, 2012 @ 8:53 pm

    Fantastic.. Cheers for your insights on the write up HTML5 Grayscale Image Hover,
    they are certainly genuinely handy… I enjoyed
    checking your content!

    Reply

  9. Lennie
    Sep 23, 2012 @ 4:59 pm

    How do you this on tumblr when customizing the blog? Like do you jus tpaste into the html codes?

    Reply

  10. Ramkumar
    Sep 25, 2012 @ 12:11 am

    Reply

  11. priya
    Sep 25, 2012 @ 12:32 am

    Excellent ! It all worked in a jiffy ! Thanks .

    Reply

  12. Annie
    Oct 5, 2012 @ 11:22 am

    Hi, this is really useful and I want to thank you for doing this. I just havea question, how do i declare multiple instances of the image in the same line of code? for example, in the line $(‘.item img’), what if I also want to declare .logo, .articles, .blog… etc… how do i declare all of them in that single code? Do i have to copy and paste the code again?

    Reply

  13. Business Logo Designer
    Oct 9, 2012 @ 9:48 am

    Thanks, this effect will look great on portfolio sites.

    Reply

  14. kiran
    Nov 27, 2012 @ 5:06 am

    Thanks for Your Tip, The demo works like magic. But My problem is that I am using WordPress and Its hard for me to achieve this. Any Help that will point me in the right direction, will be deeply appreciated.

    –Thank You.
    Skype: alokweb_kiran

    Reply

  15. Aniket
    Dec 3, 2012 @ 1:02 pm

    Oh yes…exactly what I need…You save my day..Thanks a lot…Really awesome!!!

    Reply

  16. winminsoe
    Dec 5, 2012 @ 10:53 pm

    It’s really useful.

    Is that work for the cross domain images ?
    I tested with the local image and it’s ok. But now trying to use from 500px website images, it didn’t work. By inspecting DOM , it say insecure to perform action.

    Thanks,

    Reply

  17. mreshane
    Dec 6, 2012 @ 2:02 am

    guys, if you don’t know how to applied it to your website i suggest you guys view the demo page and ctrl+u for chrome or just view the source and look out for the HTML tag, it isn’t that bad you know… they already give you the hint now you guys need to find it your self, be productive.. :D

    Cheers…

    Reply

    • winminsoe
      Dec 6, 2012 @ 2:39 am

      Dude , are you saying to me ?

      I just want to know the canvas can get the width and height of cross domain images. I didn’t say i don’t know how to applied to my site. Pls read carefully.

      Reply

  18. mreshane
    Dec 6, 2012 @ 2:32 am

    i have a question, i’ve tried to implement it to my portfolio (offline), everythings i put it at the same order, just like you taught here, but what im surprised is i the picture are loaded correctly but the jQuery files wont load, i’ve tried the new version the old version and your version but still nothing is goin on.. can you explain more?

    I’ve tried many of jQuery in offline mode but seems like yours is not functional at all or maybe im a nerd in jQuery –

    Need help here
    Thanx..

    Reply

  19. Daniel
    May 27, 2013 @ 8:03 am

    Yeah… As soon you apply javascript on the image, it stops being fluid. I’m trying to build a fluid image grid with client logos and it has to scale down the images to fit on lower resolutions. Any idea on how to achieve that?

    Reply

  20. Computer Guy
    May 31, 2011 @ 11:09 pm

    The lines below of my comment got altered by the way the page shows code.
    I have added spaces in the DIV code to hopefully make it readable.
    ————————————————————————————
    You need to put before your image and after your image.
    Or at the very least have the image inside of a
    ————————————————————————————

    Reply

  21. Computer Guy
    May 31, 2011 @ 11:16 pm

    Nope code still disappears.
    Lets try “code” and “/code” div tags in the comment.
    You need to put before your image and after your image.
    Or at the very least have the image inside of a tag named the way you want after changing the java-script to match the naming.

    Reply

  22. Computer Guy
    May 31, 2011 @ 11:17 pm

    That didn’t work either.
    How exactly do I add tags into a comment to make the appropriate changes that people can read.

    Reply

  23. Computer Guy
    May 31, 2011 @ 11:20 pm

    Another try using pre and code together to display the changes.

    You need to put before your image and after your image.
    Or at the very least have the image inside of a tag named the way you want after changing the java-script to match the class naming you use on your site.

    Reply

1 10 11 12

Leave a Reply