Today we are going to explore what I think is one of the coolest features of the canvas tag. The ability to extract and manipulate pixel data. This is an amazing feature to canvas that will help developers create all sorts of cool applications from image manipulations to code driven artwork.
I think this graphic sums it up…
Preview
I wanted to make a special graphic for this post so I cracked open Blender and came up with this HTML5 rocks 3D scene. The idea was to have a very distinct difference between the range of colors so that I could detect when I was over a orange pixel versus a grey pixel. For a surprise hover over any orangish pixel in the scene. See it in action.
Loading an image onto the Canvas
In order to get the pixels from our image we will first need to load it onto the canvas. This process is pretty simple. First we need to create some canvi : ) (Is that a word?)
<div id="canvas-container"> <canvas id="rocks-canvas" width="960" height="540">Sorry no support for canvas!</canvas> </div>
Next, we will need to load our image and shove it into the “rocks-canvas” element. Upon load we will fire an init function. Init will setup references to our canvas and canvas context. The main magic is line 11. We can take our loaded rocksImg and use the drawImage function to draw it directly to the canvas context. If you recall we used this drawImage function in our canvas spritesheet example as well.
// Load the HTML5 rocks image.
var rocksImg = new Image();
rocksImg.onload = function() {
init();
};
rocksImg.src = 'img/rocks.png';
function init(){
canvas = document.getElementById('rocks-canvas');
context = canvas.getContext('2d');
context.drawImage(rocksImg,0,0);
canvas.addEventListener('mousemove', onMouseMove, false);
}
Mouse Movin’
Once we have our image drawn we need to sample pixels based on the mouse movement. As you can see from our previous code snippet the last line is setting up the onMouseMove event so we should be ready to go. FYI, in order to keep it simple we are going to condense down the code from the working example. The full source is at the bottom if you want all the bells and whistles.
Ok so we first get ev.offsetX and ev.offsetY which will give us our mouse position. Next, we call getImageData from our canvas context and pass in the x and y coordinates followed by a width and height which in our case we want a 1px x 1px sample size. Then we call the data attribute. This will get our image data into a byteArray. The pixel data is stored in this byteArray in RGBA format. This means that our resulting pixels values in the byteArray are pixel[0] = RED, pixel[1] = GREEN, pixel[2] = BLUE, pixel[3] = ALPHA. RGB values range from 0 to 255 so each of these values returned from the byteArray will be within those ranges. The last thing we can do is check each of the RGB values for a range of colors and we could trigger something on the page if the user is on a certain color. (Example Lines 13 – 19)
function onMouseMove (ev) {
var row,column,pixel,pixelString;
column = ev.offsetX;
row = ev.offsetY;
pixel = context.getImageData(column,row,1,1).data;
pixelString = pixel[0] + "," + pixel[1] + "," + pixel[2];
//Set color swatch to our rgb value for our color swatch div element.
$colorSwatch.css('background-color', 'rgb(' + pixelString + ')');
if(pixel[0] >= 190 && pixel[0] <= 255 &&
pixel[1] >= 60 && pixel[1] <= 120 &&
pixel[2] >= 30 && pixel[2] <= 80) {
// Orange pixel range. Let's do something cool.
} else {
// Not orange pixel range.
}
}
Tip: If you want to see what the value will look like just pull up the color picker in photoshop.
Conclusion
Accessing canvas pixel data opens up many possibilites for cool and interesting projects. As always I would be interested in any cool applications of these techniques. Feel free to post a comment or link.
Source links.
Code Source
HTML5 Blend file. If you want to change the colors in the 3D file... : )





