Convert Images to Grayscale

Read this tutorial to find out how to desaturate an image (convert color images to grayscale) using JavaScript. A cross-browser code sample is supplied.
Recently we published a tutorial explaining how to rotate images using JavaScript. To continue this series of tutorials on image manipulation using JavaScript, we would like to explain how to change color images to grayscale using JavaScript.
This is a relatively simple task, but there are two methods (one method for Internet Explorer and one method for all other browsers).
Canvas Method
As you probably know, screen color consists of 3 components: red, green and blue. Each component or color (for example, red) has a value from 0 to 255. The value 0 indicates there is no red color and the value 255 would be the brightest possible red color. To convert a color to grayscale you just need to calculate the average for all three components. This can be done using the simple formula below:
grayscalecolor = (red + green + blue) / 3;
All modern browsers support the CANVAS tag which is allowed access to the image’s pixels. The code below will go through each pixel in the image and replace the color values with an average value. Here is the code:
var canvas = document.createElement('canvas'); var canvasContext = canvas.getContext('2d'); var imgW = imgObj.width; var imgH = imgObj.height; canvas.width = imgW; canvas.height = imgH; canvasContext.drawImage(imgObj, 0, 0); var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH); 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; } } canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); return canvas.toDataURL();
From the above code sample, you see that we created a canvas, loaded the image into it, and then changed the color values of each pixel in the image to an average value. After that we simply replaced the SRC of our image to the image changed in the canvas.
Using the same method you can also flip images using JavaScript. (We will create a tutorial for this in the future).
MSIE (Internet Explorer) method
Microsoft Internet Explorer does not support the CANVAS tag, but Microsoft does provide image manipulation through filters. The filter to use for converting images to grayscale is the filter named DXImageTransform.Microsoft.BasicImage. Therefore, we simply apply this filter to our image, and it will work in all versions of MSIE (starting from version 6).
imgObj.style.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)';
That’s it ;) Click the Demo to see it in action.





Evangun
January 23, 2010
Thank you, it works great.
However, in order to be able to apply grayscale on resized images, you would rather detect their size this way :
imgObj2 = new Image;
imgObj2.src = imgObj.src;
var imgW = imgObj2.width;
var imgH = imgObj2.height;
instead of
var imgW = imgObj.width;
var imgH = imgObj.height;
Cheers
ajaxBlender.com
February 1, 2010
Evangun,
Yes, your method will work as well and thank you for sharing it. I am sure some users will find this to better suit their needs. However, I should note that the method we used has been tested and works in all browsers. So, if anyone prefers this alternative method, we suggest they be sure to test it for full browser compatibility.
Alex
Chris
February 15, 2010
This is great. I’d like to turn all images with a certain class grey, and while adapting your demo if I change:
var imgObj = document.getElementById(’image’);
to
var imgObj = $(’.image’);
I get errors about uncaught exceptions. Is there a way to do what I’m trying to accomplish?
I’m not too familiar with JS so my apologies if this is a foolish question. Thanks!
ajaxBlender.com
February 18, 2010
Chris,
To turn to a certain class of grey, you may want to try this: var imgObj = $(’.image’)[0];
Thanks,
Alex
Josu3E
June 24, 2010
If your class name is “gray” so you should use:
var imgObj = $(’.gray’);
…I haven’t tested yet but it looks more logical.
eno
June 25, 2010
Nice script, tnx. But to reset the colors?
Cheers
ajaxBlender.com
July 1, 2010
Eno,
Thanks for your comment. To reset the image you should just reload the image again (for example: $(’#image-container’).html(”); )
If I didn’t understand your question correctly, just let me know.
Alex
tuba
August 12, 2010
very nice tutorial, I would like to give an effect using jquery too
dennis84
August 19, 2010
thanks for the snippet. i modified your code to this…
$.fn.greyscale = function() {
return this.each(function() {
if ($.browser.msie) {
this.style.filter = “progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)”
} else {
this.src = grayscaleImage(this)
}
})
}
function grayscaleImage(imgObj) {
…
}
$(document).ready(function() {
$(”#image”).greyscale()
})