Canvas is really an amazing thing. It can not only draw all kinds of graphics, text and bitmaps, but also perform complex pixel operations and processing on bitmaps. So things like filters can also be implemented on Canvas. Next, it was a moment of wonder.

First, we need to have a Canvas container, for example:

<canvas id="myCanvas" width="800" height="800"></canvas>
Copy the code

Next, we need to use Canvas to draw an image:

var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
var img = new Image();
img.src = "./images/1526010092000.jpg";	// Create your own image link
img.onload = (e) = > {
	ctx.drawImage(img, 0.0.800.800);	// The first 800 represents the width of the drawing image, and the second 800 represents the height of the drawing image
}
Copy the code

The next step is to do something with the pixels of the image. To achieve such an operation, the pixel information of the picture needs to be obtained from the Canvas first, which can be achieved through getImageData().

/ /... Omit the previous code
img.onload = (e) = > {
	/ /... Omit the previous code
    img = ctx.getImageData(0.0.800.800);	// Get bytes of data containing the color of each pixel
}
Copy the code

Since the size of the image is 800 * 800, the pixels are traversed to get the red, green, and blue values of each pixel. Therefore:

/ /... Omit the previous code
img.onload = (e) = > {
	/ /... Omit the previous code
    var pixelLen = 800 * 800;   // Get the number of pixels
    for(var i = 0; i < pixelLen * 4; i += 4) {
        var redC = img.data[i], // The first byte represents red
            greenC = img.data[i + 1].// The second byte represents green
            blueC = img.data[i + 2].// The third byte represents blue
            alpha = img.data[i + 3];   // The fourth byte represents transparency}}Copy the code

Through the above loop, we get the specific color value of each pixel contained in the image data; It is important to note that the data of each pixel is not one digit, but four adjacent digits representing the red, green, blue and transparent values of the point respectively. So, in fact, the array length of bitmap byte data is equal to the number of pixels multiplied by 4, which we also dealt with in the for loop.

By averaging the red, green and blue values of each point, and then assigning the generated average values to the red, green and blue values of the pixel point, the gray effect can be formed. Finally, the image can be redrawn by using putImageData() method, the code is as follows:

/ /... Omit the previous code
img.onload = (e) = > {
	/ /... Omit the previous code
    for(var i = 0; i < pixelLen * 4; i += 4) {
   		/ /... Omit the previous code
        var grey = parseInt((redC + greenC + blueC) / 3);  // Get the gray value after averaging
        img.data[i] = grey; // Change the red value
        img.data[i + 1] = grey; // Change the green value
        img.data[i + 2] = grey; // Change the blue value
    }

    ctx.putImageData(img, 0.0.800.800);  // Redraw the image
} 


Copy the code

At this point, the grayscale effect will be formed, as shown in the figure below

To control transparency, you only need to change the value of the fourth byte unit, which ranges from 0 to 256. 0 indicates full transparency and 256 indicates complete opacity. Such as:

/ /... Omit the previous code
img.onload = (e) = > {
	/ /... Omit the previous code
    for(var i = 0; i < pixelLen * 4; i += 4) {
   		/ /... Omit the previous code
        img.data[i + 3] = 128;	// Transparency 50%
    }
    / /... Omit the previous code
} 

Copy the code

Therefore, by controlling the value of 4 data in each pixel of the picture, you can achieve the effect of filter, is not so easy!

References:

“HTML5 basic knowledge, core Technology and frontier cases” edited by Liu Huan