HTML5 canvas supports that we can directly manipulate the pixel data in canvas through the imagedata object, and directly read or write the data array into the object.

Imagedata object

The imagedata object stores the real pixel data of the canvas object, which contains the following read-only attributes:

width: picture width, in pixels
height: the height of the picture, in pixels
data :A one-dimensional array of type Uint8ClampedArray , containing integer data in RGBA format, ranging from 0 to 255 (including 255))。

data Property returns a Uint8ClampedArray that can be used as the initial pixel data for viewing. Each pixel is represented by four 1 bytes values (in the order of red, green, blue, and transparent values; this is the "RGBA" format). Each color value part is represented by 0 to 255. Each part is assigned to a continuous index within the array, and the red part of the upper left pixel is at index 0 of the array. Pixels are processed from left to right, and then down through the array.

Uint8ClampedArray Contain height × width × 4 bytes data,index value form 0 to (height×width×4)-1

For example, to read the blue part of a pixel in line 50 and column 200 of a picture, you would write the following code:

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

You may use the Uint8ClampedArray.Length property to read the size of the pixel array (in bytes):

var numBytes = imageData.data.length;

Create an imagedata object

To create a new, blank imagedata object, you should use the createimagedata () method. There are 2 versions of the createimagedata() method.

var myImageData = ctx.createImageData(width, height);

The above code creates a new imagedata object of a specific size. All pixels are preset as transparent black.

You can also create an imagedata object with the same pixel specified by another imagedata object. The new object pixels are all preset as transparent black. This is not a copy of the image data.

var myImageData = ctx.createImageData(anotherImageData);

Get scene pixel data

In order to obtain an imagedata pair containing the pixel data of the canvas scene, you can use the getimagedata() method:

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

This method will return an imagedata object, which represents the object data of the canvas area. The four corners of the canvas are represented as (left, top), (left + width, top), (left, top + height), and (left + width, top + height). These coordinate points are set as canvas coordinate space elements.

Note: any element outside the canvas will be returned as a transparent black imagedata pair.


Implementation of color selector

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
};
var color = document.getElementById('color');
function pick(event) {
  var x = event.layerX;
  var y = event.layerY;
  var pixel = ctx.getImageData(x, y, 1, 1);
  var data = pixel.data;
  var rgba = 'rgba(' + data[0] + ',' + data[1] +
             ',' + data[2] + ',' + (data[3] / 255) + ')';
  color.style.background =  rgba;
  color.textContent = rgba;
}
canvas.addEventListener('mousemove', pick);

In this example, we will use getimagedata () to show the color under the mouse cursor. Therefore, we need to record the current mouse position as layerx and layery, and then we will query the pixel data in the image number array provided by getimagedata(). Finally, we use array data to set the background color and < div > text to display the color value.


Write pixel data in the scene

You can use putimagedata() method to write pixel data to the scene.

ctx.putImageData(myImageData, dx, dy);

The DX and Dy parameters represent the device coordinates of the pixel data you want to draw in the upper left corner of the scene.

For example, to draw the image represented by myimagedata in the upper left corner of the scene, you can write the following code:

ctx.putImageData(myImageData, 0, 0);

Image gray and invert color

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.onload = function() {
  draw(this);
};

function draw(img) {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
  var imageData = ctx.getImageData(0,0,canvas.width, canvas.height);
  var data = imageData.data;
    
  var invert = function() {
    for (var i = 0; i < data.length; i += 4) {
      data[i]     = 225 - data[i];     // red
      data[i + 1] = 225 - data[i + 1]; // green
      data[i + 2] = 225 - data[i + 2]; // blue
    }
    ctx.putImageData(imageData, 0, 0);
  };

  var grayscale = function() {
    for (var i = 0; i < data.length; i += 4) {
      var avg = (data[i] + data[i +1] + data[i +2]) / 3;
      data[i]     = avg; // red
      data[i + 1] = avg; // green
      data[i + 2] = avg; // blue
    }
    ctx.putImageData(imageData, 0, 0);
  };

  var invertbtn = document.getElementById('invertbtn');
  invertbtn.addEventListener('click', invert);
  var grayscalebtn = document.getElementById('grayscalebtn');
  grayscalebtn.addEventListener('click', grayscale);
}

在这个例子里,我们遍历所有像素以改变他们的数值。然后我们将被修改的像素数组通过putImageData()放回到画布中去。invert函数仅仅是去减掉颜色的最大色值255.grayscale函数仅仅是用红绿和蓝的平均值。你也可以用加权平均,例如x = 0.299r + 0.587g + 0.114b这个公式。更多资料请参考维基百科的Grayscale


Scaling and antialiasing

With the help of the DrawImage () method, the second canvas and the imagesmoothingenabled property, we can zoom in to show our pictures and see the details.

We get the position of the mouse and clip out the pictures 5 pixels to the left and top, 5 pixels to the right and 5 pixels to the bottom. Then we copy this image to another canvas and adjust the image to the size we want. In the zoom canvas, we adjust the 10 × 10 pixel clipping of the original canvas to 200 × 200.

zoomctx.drawImage(canvas, 
                  Math.abs(x - 5), Math.abs(y - 5),
                  10, 10, 0, 0, 200, 200);

Because antialiasing is on by default, we may want to turn it off to see clear pixels. You can see the effect of the imagesmoothingenabled property by switching the checkboxes (different browsers need different prefixes).

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.onload = function() {
  draw(this);
};

function draw(img) {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
  var zoomctx = document.getElementById('zoom').getContext('2d');
 
  var smoothbtn = document.getElementById('smoothbtn');
  var toggleSmoothing = function(event) {
    zoomctx.imageSmoothingEnabled = this.checked;
    zoomctx.mozImageSmoothingEnabled = this.checked;
    zoomctx.webkitImageSmoothingEnabled = this.checked;
    zoomctx.msImageSmoothingEnabled = this.checked;
  };
  smoothbtn.addEventListener('change', toggleSmoothing);

  var zoom = function(event) {
    var x = event.layerX;
    var y = event.layerY;
    zoomctx.drawImage(canvas,
                      Math.abs(x - 5),
                      Math.abs(y - 5),
                      10, 10,
                      0, 0,
                      200, 200);
  };

  canvas.addEventListener('mousemove', zoom);
}

More information : Pixel Operation - Web API