HTML and CSS Reference
In-Depth Information
See Also
9.6 Setting Color Transformations
Problem
You want to apply a color transformation (like grayscale or invert) to an existing
canvas
drawing.
Solution
The
canvas
API provides a command called
getImageData(...)
that grabs all the pixel
color data from the
canvas
element, handing it to you in one long array:
var drawing = mycontext.getImageData(0, 0, 200, 200);
The array you get from
getImageData(...)
is not in quite the format
you'd generally expect. First, it's not a two-dimensional array, with
width and height dimensions. Instead, it is a linear single-dimension
array, where the values wrap from one line to the next, like a big long
string of text that you paste into a text editor.
Second, there are four consecutive entries in the array for each pixel,
each entry corresponding to a color component for a pixel. So, each
pixel takes up four entries in the array, in the form of
[...,
red
,
green
,
blue
,
alpha
, ...]
.
Once you have the image data captured, you can manipulate that data using any trans-
formations you please and then write it back to the
canvas
element.
To grayscale the drawing, the simplest algorithm is to take the average of the red, green,
and blue color components and set all three to that average value:
var avg;
// skip 4 entries (1 px) at a time
for (var i = 0; i < drawing.data.length; i = i + 4) {
avg = (drawing.data[i] + drawing.data[i+1] + drawing.data[i+2]) / 3;
drawing.data[i] = drawing.data[i+1] = drawing.data[i+2] = avg;
}
To color-invert the drawing, the simplest algorithm is to take each color component
value, subtract it from 255, and set that color value back:
// skip 4 entries (1 px) at a time
for (var i = 0; i < drawing.data.length; i = i + 4) {
drawing.data[i] = 255 - drawing.data[i];
// invert red
drawing.data[i+1] = 255 - drawing.data[i+1];
// invert green