Is there a simple way to display a color bitmap in grayscale with just HTML/CSS
?
It doesn\'t need to be IE-compatible (and I imagine it won\'t be) -- if
Simplest way to achieve grayscale with CSS exclusively is via the filter
property.
img {
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
The property is still not fully supported and still requires the -webkit-filter
property for support across all browsers.
If you're willing to use Javascript, then you can use a canvas to convert the image to grayscale. Since Firefox and Safari support <canvas>
, it should work.
So I googled "canvas grayscale", and the first result was http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html which seems to work.
For grayscale as a percent in Firefox, use saturate filter instead: (search for 'saturate')
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"
Update: I made this into a full GitHub repo, including JavaScript polyfill for IE10 and IE11: https://github.com/karlhorky/gray
I originally used SalmanPK's answer, but then created the variation below to eliminate the extra HTTP request required for the SVG file. The inline SVG works in Firefox versions 10 and above, and versions lower than 10 no longer account for even 1% of the global browser market.
I have since been keeping the solution updated on this blog post, adding support for fading back to color, IE 10/11 support with SVG, and partial grayscale in the demo.
img.grayscale {
/* Firefox 10+, Firefox on Android */
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://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>#grayscale");
/* IE 6-9 */
filter: gray;
/* Chrome 19+, Safari 6+, Safari 6+ iOS */
-webkit-filter: grayscale(100%);
}
img.grayscale.disabled {
filter: none;
-webkit-filter: grayscale(0%);
}
Following on from brillout.com's answer, and also Roman Nurik's answer, and relaxing somewhat the the 'no SVG' requirement, you can desaturate images in Firefox using only a single SVG file and some CSS.
Your SVG file will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg">
<filter id="desaturate">
<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>
Save that as resources.svg, it can be reused from now on for any image you want to change to greyscale.
In your CSS you reference the filter using the Firefox specific filter
property:
.target {
filter: url(resources.svg#desaturate);
}
Add the MS proprietary ones too if you feel like it, apply that class to any image you want to convert to greyscale (works in Firefox >3.5, IE8).
edit: Here's a nice blog post which describes using the new CSS3 filter
property in SalmanPK's answer in concert with the SVG approach described here. Using that approach you'd end up with something like:
img.desaturate{
filter: gray; /* IE */
-webkit-filter: grayscale(1); /* Old WebKit */
-webkit-filter: grayscale(100%); /* New WebKit */
filter: url(resources.svg#desaturate); /* older Firefox */
filter: grayscale(100%); /* Current draft standard */
}
Further browser support info here.
Based on robertc's answer:
To get proper conversion from colored image to grayscale image instead of using matrix like this:
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
You should use conversion matrix like this:
0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0 0 0 1
This should work fine for all the types of images based on RGBA (red-green-blue-alpha) model.
For more information why you should use matrix I posted more likely that the robertc's one check following links: