Evangelism/Firefox3.5/35Days/Articles/createImageData: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 3: Line 3:
== Canvas: Welcome into the matrix ==
== Canvas: Welcome into the matrix ==


The canvas element give you a way to draw bitmap data into a HTML page.
The canvas element gives you a way to draw bitmap data into a HTML page.
You can draw rectangles, lines, paths, etc.
You can draw rectangles, lines, paths, etc.
But something you may not know is that you have a direct access to the pixels values.
But something you may not know is that you have a direct access to the pixels values.
Line 22: Line 22:
A pixel is a set of 4 values (0..255): red, green, blue, alpha.
A pixel is a set of 4 values (0..255): red, green, blue, alpha.


The alpha channel allow opacity (0: transparent, 255: opaque).
The alpha channel allows opacity (0: transparent, 255: opaque).


The pixels values are stored in a one dimension vector, a Javascript Array.
The pixels values are stored in a one dimension vector, a Javascript Array.
Line 28: Line 28:
The size of this array is: ''width * height * 4''.
The size of this array is: ''width * height * 4''.


That means if you want to know the blue value of the pixel ''x: 10, y: 20'', just do:
That means, if you want to know the blue value of the pixel ''x: 10, y: 20'', just do:
  var blue = canvasData.data[(y * width + x) * 4 + 2];
  var blue = canvasData.data[(y * width + x) * 4 + 2];


Line 51: Line 51:
If you want to create a new matrix from scratch, just use the ''createImageData'', which needs two arguments: the height and the width of the matrix.
If you want to create a new matrix from scratch, just use the ''createImageData'', which needs two arguments: the height and the width of the matrix.


For example, if you want to create a set of pixels that fit the canvas size:
For example, if you want to create a set of pixels that fits the canvas size:


  var canvas = document.getElementById('myCanvasElt');
  var canvas = document.getElementById('myCanvasElt');
Line 84: Line 84:
==== Update the canvas ====
==== Update the canvas ====


Ok, now, you know how to create a matrix. But if you change the values, it will not by applied to the canvas directly, you have to push the matrix to the canvas. That can be done via the ''putImageData'' method, which takes 3 arguments: ''ImageData'', x, y (coordinates of where in the canvas put the matrix).
Ok, now, you know how to create a matrix. But if you change the values, they will not be applied to the canvas directly, you have to push the matrix to the canvas. That can be done via the ''putImageData'' method, which takes 3 arguments: ''ImageData'', x, y (coordinates of where in the canvas to put the matrix).


=== Examples ===
=== Examples ===


==== getImageData ====
==== getImageData ====
Here is a code that transform your image to a gray scale:
Here is a code that transforms your image to a gray scale:


  var canvas = document.getElementById('myCanvasElt');
  var canvas = document.getElementById('myCanvasElt');
Line 117: Line 117:


==== createImageData ====
==== createImageData ====
Here is a code the draw a fractal:
Here is a code to draw a fractal:


  var canvas = document.getElementById('myCanvasElt');
  var canvas = document.getElementById('myCanvasElt');
Line 164: Line 164:
=== Documentation ===
=== Documentation ===


If you want to know more about Canvas and pixels manipulation, I strongly encourage you to see the MDC documentation:
If you want to know more about Canvas and pixels manipulation, I strongly encourage you to browse the MDC documentation:
* https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas
* https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas
* https://developer.mozilla.org/En/HTML/Canvas/
* https://developer.mozilla.org/En/HTML/Canvas/
* https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas
* https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas

Revision as of 11:24, 3 June 2009

Work in progress

Canvas: Welcome into the matrix

The canvas element gives you a way to draw bitmap data into a HTML page. You can draw rectangles, lines, paths, etc. But something you may not know is that you have a direct access to the pixels values.

The structure

A canvas is a matrix of pixels.

The canvas data is a Javascript object. We will see later how to retrieve this object.

canvasData {
  width: unsigned long, // the width of the canvas
  height: unsigned long, // the height of the canvas
  data: CanvasPixelArray // the values of the pixels
}

A pixel is a set of 4 values (0..255): red, green, blue, alpha.

The alpha channel allows opacity (0: transparent, 255: opaque).

The pixels values are stored in a one dimension vector, a Javascript Array.

The size of this array is: width * height * 4.

That means, if you want to know the blue value of the pixel x: 10, y: 20, just do:

var blue = canvasData.data[(y * width + x) * 4 + 2];

Pixel manipulation

There are 2 ways to retrieve this array:

The values of the current canvas

You can play with current values of the canvas. If you've already drawn something on your canvas, you may want to modify it. You can retrieve all the pixels, or a subpart of the canvas (as a rectangle). The method to use the current data is getImageData, which needs 4 parameters: x, y, width, height (Coordinates of the subpart of the canvas you want to reach).

For example, if you want to retrieve all the pixels:

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);

Then, you can play with the pixels values (stored in canvasData.data).

Create a new set of pixels

If you want to create a new matrix from scratch, just use the createImageData, which needs two arguments: the height and the width of the matrix.

For example, if you want to create a set of pixels that fits the canvas size:

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.createImageData(canvas.width, canvas.height);

Update the pixels

Here is the classic way to update the pixels values:

for (var x = 0; x < canvasData.width; x++) {
  for (var y = 0; y < canvasData.height; y++) {

    // Index of the pixel in the array
    var idx = (x + y * width) * 4;

    // If you want to know the values of the pixel
    var r = canvasData.data[idx + 0];
    var g = canvasData.data[idx + 1];
    var b = canvasData.data[idx + 2];
    var a = canvasData.data[idx + 3];
    //[...] do what you want with these values

    // If you want to update the values of the pixel
    canvasData.data[idx + 0] = ...; // Red channel
    canvasData.data[idx + 1] = ...; // Green channel
    canvasData.data[idx + 2] = ...; // Blue channel
    canvasData.data[idx + 3] = ...; // Alpha channel
  }
}

Update the canvas

Ok, now, you know how to create a matrix. But if you change the values, they will not be applied to the canvas directly, you have to push the matrix to the canvas. That can be done via the putImageData method, which takes 3 arguments: ImageData, x, y (coordinates of where in the canvas to put the matrix).

Examples

getImageData

Here is a code that transforms your image to a gray scale:

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var x = 0; x < canvasData.width; x++) {
  for (var y = 0; y < canvasData.height; y++) {

    // Index of the pixel in the array
    var idx = (x + y * canvas.width) * 4;

    // The RGB values
    var r = canvasData.data[idx + 0];
    var g = canvasData.data[idx + 1];
    var b = canvasData.data[idx + 2];

    // Update the values of the pixel;
    var gray = (r + g + b) / 3;
    canvasData.data[idx + 0] = gray;
    canvasData.data[idx + 1] = gray;
    canvasData.data[idx + 2] = gray;
  }
}
ctx.putImageData(canvasData, 0, 0);

See in action http://people.mozilla.com/~prouget/demos/35days/gray.xhtml

createImageData

Here is a code to draw a fractal:

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.createImageData(canvas.width, canvas.height);

// Mandelbrot
function computeColor(x, y) {
    x = 2.5 * (x/canvas.width - 0.5);
    y = 2 * (y/canvas.height - 0.5);
    var x0 = x;
    var y0 = y;

    var iteration = 0;
    var max_iteration = 100;

    while (x * x + y * y <= 4 && iteration < max_iteration ) {
        var xtemp = x*x - y*y + x0;
        y = 2*x*y + y0;
        x = xtemp;
        iteration++;
    }
    return Math.round(255 * iteration / max_iteration);
}

for (var x = 0; x < canvasData.width; x++) {
    for (var y = 0; y < canvasData.height; y++) {


        var color = computeColor(x, y);

        // Index of the pixel in the array
        var idx = (x + y * canvas.width) * 4;

        // Update the values of the pixel;
        canvasData.data[idx + 0] = color;
        canvasData.data[idx + 1] = color;
        canvasData.data[idx + 2] = color;
        canvasData.data[idx + 3] = 255;
    }
}
ctx.putImageData(canvasData, 0, 0);

See in action: http://people.mozilla.com/~prouget/demos/35days/fractal.xhtml.

Documentation

If you want to know more about Canvas and pixels manipulation, I strongly encourage you to browse the MDC documentation: