Canvas judges whether the brush fills the area

16055211:

Determine whether the canvas shape is filled and the percentage

insert image description here

<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.strokeStyle = "#FF0000";
ctx.rect(20,20,150,100);
ctx.stroke();
	
	//模拟用户画笔填充
	ctx.fillStyle="#FF0000";
	ctx.fillRect(20,20,80,80);
	//获取画布中数据
	/*
	*	对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
		R - 红色(0-255)
		G - 绿色(0-255)
		B - 蓝色(0-255)
		A - alpha 通道(0-255; 0 是透明的,255 是完全可见的)
	*/
	var imgData=ctx.getImageData(20,20,150,100);
</script> 

insert image description here

    After the drawing is completed, use ctx.getImageData()the method to get the return format of the canvas 像素数据: Uint8ClampedArray.
Traverse the pixel data to determine whether the color value of each pixel is equal to the color of the brush. If they are equal, it means that the pixel was drawn by a brush;
if not, it means that the pixel was not drawn by a brush or the user did not fill it.
According to the result of the traversal, it can be judged whether the brush covers the entire canvas.
If it is difficult to understand, just look at the bottom (tail) picture and then look at

insert image description here
it. It is similar to this, where A is 255
insert image description here

Here is a sample code:

// 获取绘图上下文和绘图目标  
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.strokeStyle = "#FF0000";
ctx.rect(20,20,150,100);
ctx.stroke();
	
	//模拟用户画笔填充
	ctx.fillStyle="#FF0000";
	ctx.fillRect(20,20,80,80);
	//获取画布中数据 获取像素数据  
	/*
	*	对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
		R - 红色(0-255)
		G - 绿色(0-255)
		B - 蓝色(0-255)
		A - alpha 通道(0-255; 0 是透明的,255 是完全可见的)
	*/
	var imgData=ctx.getImageData(20,20,150,100);
  
	let data = imageData.data;  
  
	// 遍历像素数据,判断画笔是否铺满整个画布  
	let isFull = true;  
	for (let i = 0; i < data.length; i += 4) {
    
      
	    if (data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255) {
    
      
	        isFull = false;  
	        break;  
	    }  
	}  
  
	// 判断结果输出  
	console.log(isFull ? '已铺满' : '未铺满');

In the above sample code, assuming that the color of the brush is red (RGB value is 255,0,0), when traversing the pixel data, it is judged whether the RGB value of each pixel is red. If there are other colors, it means that the canvas is not blocked. Paved.
The filled pixel data is as follows:
insert image description here
the unfilled place is as follows:
insert image description here
percentage judgment:

For example, for this square, the percentage can be obtained by if (data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255) judging the pixel data when it meets the requirements of the user's brush, and the ratio of the total points, such as:

//满足用户在该形状中所画的图像数据点
let drawCount = 0; //满足的像素点
let total = data.length/4;   //总共像素点
if (!(data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255)){
    
    
	drawCount++;
}
//在区域形状内,用户画的比例
console.log((drawCount / total)*100+'%' )

The above is to obtain the getImageData method through content '2d', that is, "CanvasRenderingContext2D".
Note webglthat there is no directly corresponding method function webgl2
WebGLRenderingContextin the API . However, there are methods available to obtain pixel data for rendering onto a WebGL canvas.CanvasRenderingContext2DgetImageDataWebGLRenderingContextreadPixels

The basic usage of the readPixels method is as follows:

//获取WebGLRenderingContext对象:
var gl = canvas.getContext('webgl');
var pixels = new Uint8Array(canvas.width * canvas.height * 4);  
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels)

The first two parameters of this method are the starting x and y coordinates, usually you can set them both to 0, because WebGL is an opaque rendering context. The next two parameters are the read width and height, you should also set both of them to the width and height of the canvas to get the pixel data for the entire canvas. The last parameter is an ArrayBufferView object used to store the read pixel data.
insert image description here

Note that readPixelsthe method may not work in all browsers, especially some old browsers or some specific mobile devices may not support this function.

Also, note that although readPixels returns a Uint8ClampedArray with values ​​between 0 and 255, not the pixel data format of CanvasRenderingContext2D's getImageData - a Float32Array with values ​​between 0 and 1.

In some cases, you may need to convert WebGL pixel data to CanvasRenderingContext2D format. This can be done with:

var imageData = new ImageData(new Uint8ClampedArray(pixels), canvas.width, canvas.height);

insert image description here

In this example, we first create a new Uint8ClampedArray and copy the WebGL pixel data into it. We then created a new ImageData object with this new array. This new ImageData object can be used directly in CanvasRenderingContext2D methods such as putImageData.


Determine whether the canvas shape is full, determine whether the player is filled in the canvas shape, and determine the percentage of the player's painted shape

Guess you like

Origin blog.csdn.net/mingketao/article/details/131344391