How to Convert Web Images to Grayscale: 3 Easy Methods

I’ve always been a fan of grayscale images because they look more artistic. Many photo editors, like Photoshop, allow you to turn colorful images into grayscale effortlessly, even offering options to adjust color depth and tones. However, achieving the same effect on the web can be tricky due to varying browser capabilities.

In this post, we’ll explore several methods to convert images to grayscale on the web. We’ll discuss the pros and cons of each approach and, towards the end, we’ll combine these methods to create a solution that works across different browsers.

How to Apply CSS Filter Effects to Web Images

How to Apply CSS Filter Effects to Web Images

Adjusting image Brightness and Contrast, or turning image into Grayscale or Sephia is a common feature you may... Read more

1. CSS Filter

Using the CSS filter property is perhaps the easiest way to convert an image to grayscale. In the past, Internet Explorer had a proprietary CSS property called filter to apply custom effects, including grayscale.

Today, the filter property is part of the CSS3 specification and is supported in several browsers, such as Firefox, Chrome, and Safari. Previously, we also discussed the Webkit filter that allows us to apply not only grayscale but also sepia and blur effects.

We can add the following style rules to convert images to grayscale using the filter property:

img {
  -webkit-filter: grayscale(1);  /* Webkit */
  filter: gray;  /* IE6-9 */
  filter: grayscale(1);  /* W3C */
}

This code will take effect in IE6-9 and Webkit browsers (Chrome 18+, Safari 6.0+, and Opera 15+).

Note: IE10 dropped support for the legacy IE filter and also does not support the prefixed version, -ms-filter, for applying grayscale. This code does not work in Firefox either.

2. JavaScript

The second method is using JavaScript, which should work in all browsers with JavaScript enabled, including older versions like IE6 and below.

var imgObj = document.getElementById('js-image');

function gray(imgObj) {
  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();
}

imgObj.src = gray(imgObj);

Using the JavaScript method, we can apply the grayscale effect under certain conditions, such as when the image is hovered over or clicked. We can also use it with jQuery effects to apply smooth animations when transitioning from gray to full color. The only downside is that this effect will not work if JavaScript is disabled in the browser.

3. SVG

Another method is by using an SVG Filter.

To do this, create an SVG file and add the following code. Save and name the file, for example, gray.svg.

<svg xmlns="https://www.w3.org/2000/svg">
  <filter id="grayscale">
    <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"/>
  </filter>
</svg>

Then, use the filter property to link the SVG file, followed by the ID of the filter element in our SVG file:

img {
  filter: url('img/gray.svg#grayscale');
}

You can also embed the code directly within the CSS, like this:

img {
  filter: url('url("data:image/svg+xml;utf8,<svg%20xmlns='https://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale");')
}

This will yield the same result.

Conclusion

To achieve cross-browser support for the grayscale effect, we can combine the methods mentioned above using the following code snippet. This code will apply the grayscale effect in Firefox 3.5+, Opera 15+, Safari, Chrome, and Internet Explorer.

img {
  -webkit-filter: grayscale(100%);
  -webkit-filter: grayscale(1);
  filter: grayscale(100%);
  filter: url('../img/gray.svg#grayscale');
  filter: gray;
}

We can use the above code along with the JavaScript method and only provide the CSS filter as a fallback in case JavaScript is disabled. This approach can easily be implemented with the help of Modernizr.

Modernizr will add a js class to the body if JavaScript is enabled, and will switch the class name to no-js if it is disabled. With CSS, you can do the following:

.no-js img {
  -webkit-filter: grayscale(100%);
  -webkit-filter: grayscale(1);
  filter: grayscale(100%);
  filter: url('../img/gray.svg#grayscale');
  filter: gray;
}

That's all! You can see the demo in action below:

View dmeo Download source

Sources

Check out the following sources for references on grayscale and the filter effect:

WebsiteFacebookTwitterInstagramPinterestLinkedInGoogle+YoutubeRedditDribbbleBehanceGithubCodePenWhatsappEmail