Content summary: This article shows the common interface of canvas in image pixel data operation through simple code examples and slightly obscene picture demos. As for how to use these interfaces to achieve more complex effects, it will continue to be discussed in subsequent chapters.
1. Canvas image filling; 2. Set/get canvas image data; 3. Create canvas image data; 4. A little supplement to imageData.data; 5. Write it later
1. Canvas picture filling/**
* @description
* @param {Number} x The distance from the leftmost point of the image starting drawing point from canvas
* @param {Number} y The distance between the starting point of the image drawing from the top of the canvas
* @param {Number} width The width of the final image drawn on canvas
* @param {Number} height The height of the final image drawn on canvas
*/
context.drawImage(image, x, y, width, height)
demo_01 is as follows:
<canvas id=draw_image_canvas style=background:#ccc;></canvas>
function $(id) { return document.getElementById(id); }
function getImage(url, callback){
var img = document.createElement('img');
img.onload = function(){
callback && callback(this);
};
img.src = url;
document.body.appendChild(img);
}
function drawImage(){
var url = 'xiangjishi.png';
var canvas = $('draw_image_canvas');
var context = canvas.getContext('2d');
getImage(url, function(img){
canvas.width = img.width;
canvas.height = img.height;
var offsetX = 20;
var offsetY = 20;
var drawWidth = img.width/4;
var drawHeight = img.height/4;
context.drawImage(img, offsetX, offsetY, drawWidth, drawHeight);
});
}
drawImage();
demo description: Load xiangjishi.png. After loading, draw xiangjishi.png on the canvas starting from the coordinates (0, 0) relative to the upper left corner of the canvas. The effect is as follows:
Seeing this, you may not understand the meaning of the four parameters in context.drawImage(image, x, y, width, height) yet. You can simply modify a few parameters to see the effect:
var offsetX = 20;
var offsetY = 20;
var drawWidth = img.width/2;
var drawHeight = img.height/2;
context.drawImage(img, offsetX, offsetY, drawWidth, drawHeight);
The modified demo effect is as follows. Combined with the above API description, it should not be difficult to understand the meaning of the four parameters.
context.drawImage(image, x, y, width, height)
2. Get/set canvas picture data/**
* @description Get pixel information for a specific area of canvas
* @param {Number} x The distance from the leftmost point of the information to obtain the distance from the canvas
* @param {Number} y The starting distance from the top of the canvas for information
* @param {Number} width The width obtained
* @param {Number} height The final height
*/
context.getImageData(x, y, width, height)
This method returns an ImageData object, which has three main properties:
imageData.width: How many elements are there per line
imageData.height: How many elements are there per column
imageData.data: One-dimensional array that stores the RGBA value of each pixel obtained from canvas. This array saves four values for each pixel - red, green, blue, and alpha transparency. Each value is between 0 and 255. Therefore, each pixel on canvas becomes four integer values in this array. The order of filling of the array is from left to right, from top to bottom.
/**
* @description Set the pixel information of a specific area with a specific imageData
* @param {Number} x Start setting from the x point of canvas
* @param {Number} y Start setting from the y point of canvas
* @param {Number} width The width obtained
* @param {Number} height The final height
*/
context.putImageData(imageData, x, y)
The following is to combine demo_2 to explain the usage of getImageData() and the corresponding meaning of each parameter
The source code of DEMO_02 is as follows, and it is slightly modified based on demo_01:
<canvas id="draw_image_canvas" style="background:#cc;"></canvas>
<canvas id="get_image_canvas" style="background:#cc;"></canvas>
function getAndSetImageData(){
var url = 'xiangjishi.png';
getImage(url, function(img){
$('draw_image_canvas').width = img.width;
$('draw_image_canvas').height = img.height;
var context = $('draw_image_canvas').getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);
//Get pixel information
var offsetX = img.width/2;
var offsetY = img.height/2;
var getImgWidth = img.width/2;
var getImgHeight = img.height/2;
var imgageData = context.getImageData(offsetX, offsetY, getImgWidth, getImgHeight);
//Set pixel information, ignore the specific code here first, know that the pixel information obtained above is placed in another canvas intact
var startX = 0;
var startY = 0;
var ct = $('get_image_canvas').getContext('2d');
$('get_image_canvas').width = img.width;
$('get_image_canvas').height = img.height;
ct.putImageData(imgageData, startX, startY);
});
}
The demo_2 display effect is as follows :At this point, the meaning corresponding to the four parameters of the getImageData method can be basically cleared. It is not difficult to understand putImageData parameters. After slightly modifying the code of demo_2, you will know it after looking at the effect.
function getAndSetImageData(){
var url = 'xiangjishi.png';
getImage(url, function(img){
$('draw_image_canvas').width = img.width;
$('draw_image_canvas').height = img.height;
var context = $('draw_image_canvas').getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);
//Get pixel information
var offsetX = img.width/2;
var offsetY = img.height/2;
var getImgWidth = img.width/2;
var getImgHeight = img.height/2;
var imgageData = context.getImageData(offsetX, offsetY, getImgWidth, getImgHeight);
//Set pixel information
var startX = img.width/2; //This was originally 0
var startY = img.width/2; //This was originally 0
var ct = $('get_image_canvas').getContext('2d');
$('get_image_canvas').width = img.width;
$('get_image_canvas').height = img.height;
ct.putImageData(imgageData, startX, startY);
});
}
The demo_3 display effect is as follows, but if you try to change a few parameters yourself, you may have a better understanding:
3. Create canvas image data/**
* @description Pre-create a set of image data and bind it to the canvas object
* @param {Number} width Created by width
* @param {Number} height Created height
*/
context.createImageData(width, height)
The interface is relatively simple, and the created data can be processed the same as the data obtained with getImageData. It only needs to be noted here that this set of image data may not necessarily reflect the current state of canvas.
4. Some supplements about imageDataIn addition, in "HTML5 Advanced Programming" and many articles, imageData.data is regarded as an array, but in fact:
imageData.data returns not a real array, but an object of class array, which can print out the type of imageData.data.
console.log(Object.prototype.toString.call(imgageData.data)); //Output: [object Uint8ClampedArray]
Then print out the specific content of imageData.data. The content is long. Only the first and last paragraphs can be seen:
imageData.data is actually an object whose index starts from 0 and ends up to width*height*4-1.
Why not store it directly in arrays? Because the length of the array has an upper limit, assuming it is limitLength, elements that exceed limitLength are stored in key values. For example, data[limitLength + 100] is actually data['limitLength + 100 + ''] (I can't remember the specific value of limitLength, if you are interested, you can check it out)
As for the byteLength, byteOffset, and buffer properties at the end, we have not investigated in depth, and we will not expand it here to prevent misleading readers.
5. Write it at the backLimited level, please point out if there are any errors