Pixel manipulation with canvas

Introduced in Gecko 1.9

(Firefox 3)

You can directly manipulate pixel data in canvases at the byte level using the ImageData object, which has three fields:

width
The width of the image in pixels; this is a read only unsigned long.
height
The height of the image in pixels; this is a read only unsigned long.
data
A CanvasPixelArray object containing the image data.

The CanvasPixelArray object can be accessed to look at the raw pixel data; each pixel is represented by four one-byte values (red, green, blue, and alpha, in that order; that is, "RGBA" format). Each color component is represented by an integer between 0 and 255. Each component is assigned a consecutive index within the array, with the top left pixel's red component being at index 0 within the array. Pixels then proceed from left to right, then downward, throughout the array.

The CanvasPixelArray contains height x width x 4 bytes of data, with index values ranging from 0 to (height x width x 4)-1.

For example, to read the blue component's value from the pixel at column 200, row 50 in the image, you would do the following:

blueComponent = imageData.data[((50*(imageData.width*4)) + (200*4)) + 2];

You may access the size of the pixel array in bytes by reading the CanvasPixelArray.length attribute:

var numBytes = imageData.data.length;

Creating an ImageData object

Gecko 1.9.1 note
Applies to Firefox 3.5 and Thunderbird 3 and later

To create a new, blank ImageData object, you should use the createImageData() method. This creates an ImageData object optimized for best performance with the other ImageData manipulation methods. There are two versions of the createImageData() method:

var myImageData = context.createImageData(cssWidth, cssHeight);

This creates a new ImageData object with the specified dimensions as specified in CSS pixels. Note that these dimensions may be different from the number of actual device pixels in the resulting object, so you should check the dimensions of the resulting object. All pixels are preset to transparent black.

var myImageData = context.createImageData(anotherImageData);

This version of the createImageData() method creates a new ImageData object with the same dimensions as the object specified by anotherImageData. The new object's pixels are all preset to transparent black.  This does not copy the image data!

The createImageData() method is not available in Gecko 1.9 based applications (including Firefox 3); for these applications, you will need to manually construct the ImageData object. However, performance may degrade if you do this, so when possible, you should use createImageData().

Getting the pixel data for a context

To obtain an ImageData object containing a copy of the pixel data for a context, you can use the getImageData() method:

var myImageData = context.getImageData(left, top, width, height);

This method returns an ImageData object representing the pixel data for the area of the canvas whose corners are represented by the points (left, top), (left+width, top), (left, left+height), and (left+width, top+height). The coordinates are specified in canvas coordinate space units.

Note: Any pixels outside the canvas are returned as transparent black in the resulting ImageData object.

This method is demonstrated in the article Manipulating video using canvas.

Painting pixel data into a context

You can use the putImageData() method to paint pixel data into a context:

context.putImageData(myImageData, dx, dy);

The dx and dy parameters indicate the device coordinates within the context at which to paint the top left corner of the pixel data you wish to draw.

For example, to paint the entire image represented by myImageData to the top left corner of the context, you can simply do the following:

context.putImageData(myImageData, 0, 0);
Gecko does not currently implement the optional dirtyX, dirtyY, dirtyWidth, and dirtyHeight arguments specified in HTML5; see bug 498826