The original address

The main content

In the last article, we learned how to get Canvas pixels — portals. Today, we will learn how to manipulate Canvas pixels.

One method: putImageData

putImageData

Usage:

context.putImageData(imgData, x, y, dX, dY, dWidth, dHeight);
Copy the code
parameter describe
imgData Specifies the ImageData object to be put back into the canvas.
x The x-coordinate of the upper left corner of the ImageData object, in pixels.
y The y coordinate of the upper left corner of the ImageData object, in pixels.
dX Optional. Horizontal value (x), in pixels, the position of the image on the canvas.
dY Optional. Horizontal value (y), in pixels, the position of the image on the canvas.
dWidth Optional. The width used to draw the image on the canvas.
dHeight Optional. The height used to draw the image on the canvas.

Below chestnut simple realization of a few simple filter effect, specific algorithm reference here, learned “digital image processing” students should understand this more profound.

demo

The filter attribute of CSS3 can be used efficiently and easily to highlight effects rather than data.

Part of the code

import imgUrl from './component/sample.jpg';

export default {
	data () {
		return {
			imgUrl: imgUrl
		}
	},

	methods: {
		onOperate1 () {
			this.ctx.putImageData(this.onCompute1(), 0.0);
		},

		onOperate2 () {
			this.ctx.putImageData(this.onCompute2(), 0.0); },... onCancel () {this.reload();
		},

		onCompute1 () {
			let data = this.frameData.data;

	        for (let i = 0; i < this.imgDataLength; i += 4) {
	          	let r = data[i + 0],
	          		g = data[i + 1],
	          		b = data[i + 2];
	          	
          		data[i + 0] = 255 - r;
          		data[i + 1] = 255 - g;
          		data[i + 2] = 255 - b;
	        }

	        return this.frameData;
		},

		onCompute2 () {
			let data = this.frameData.data;

	        for (let i = 0; i < this.imgDataLength; i += 4) {
	          	data[i] = Math.abs(data[i + 1] - data[i + 2] + data[i + 1] + data[i]) * data[i] / 256;  
            	data[i + 1] = Math.abs(data[i + 2] - data[i + 1] + data[i + 2] + data[i]) * data[i] / 256;  
            	data[i + 2] = Math.abs(data[i + 2] - data[i + 1] + data[i + 2] + data[i]) * data[i + 1] / 256;
	        }

	        return this.frameData; },... }, mounted () {this.canvas = this.$refs['canvas'];
        this.ctx = this.canvas.getContext('2d');

        this.reload(); }}Copy the code

Last week, I went to the Nanshan Bamboo Sea of Tianmu Lake in Liyang with my classmates. I was fooled into taking a photo in the scenic area, which is this one

Then I was teased by my circle of friends. Actually at that time is standing in front of a green screen patted 😂.

The magic wand tool in PS can select and empty all the similar pixels under a certain tolerance in the picture, and easily achieve one-click “matting”. The premise is that the main body must have a big difference with the background, that is, the larger the pixel value difference, the better the matting effect.

Canvas can do the same and handle video frames. The principle is the same — set the opacity of the green screen pixels in each video frame to 0. Like this –

demo

Part of the code

import videoUrl from './component/video.ogv';
import imgUrl from './component/sample.jpg';

const TOLERANCE = 5;
export default {
	data () {
		return {
			videoUrl: videoUrl,
			imgUrl: imgUrl
		}
	},

	methods: {
		draw () {
			if (this.video.paused || this.video.ended) {
	          	return;
	        }
			this.ctx.drawImage(this.video, 0.0.this.width, this.height);
			this.ctx.putImageData(this.cutOut(), 0.0);
		},

		cutOut () {
			let frameData = this.ctx.getImageData(0.0.this.width, this.height),
				len = frameData.data.length / 4;

	        for (let i = 0; i < len; i++) {
	          	let r = frameData.data[i * 4 + 0],
	          		g = frameData.data[i * 4 + 1],
	          		b = frameData.data[i * 4 + 2];
	          	if (r - 100 >= TOLERANCE 
	          	 && g - 100 >= TOLERANCE 
	          	 && b - 43 <= TOLERANCE) {
		            frameData.data[i * 4 + 3] = 0; }}return frameData;
		}
	},

	mounted () {
		this.video = this.$refs['video'];
        this.canvas = this.$refs['canvas'];
        this.ctx = this.canvas.getContext('2d');
        this.timer = null;

        this.video.addEventListener('play', () = > {this.width = this.video.videoWidth;
            this.height = this.video.videoHeight;

            this.timer && clearInterval(this.timer);
            this.timer = setInterval((a)= > {
            	this.draw();
            }, 50);
        }, false); }}Copy the code

The resources

  • Manipulating video using canvas
  • Pixel manipulation with canvas
  • Canvas and images and pixels
  • www.jianshu.com/p/90f6aedb3…