(using the canvas solution)
Here's an algorithmic question that is a bit relevant and interesting to the front end.
Topic:
There are several non-specific shapes on a plane, as shown in. Please write the program to find out the number of objects, and the area of each different object.
Analysis
To know how many graphs there are, the idea is to get each pixel in the picture first and then get the background color (RGBA) of the pixel point. To get every pixel in the picture, you can associate a canvas with H5.
As follows:
The Getimagedata method of canvas in the Novice tutorial http://www.runoob.com/tags/canvas-getimagedata.html
Write HTML tags.
<canvas id="canvas" height="200" width="350">对不你,你的浏览器不支持Canvas</canvas>
JS Get Canvas Object
let ctxt = canvas.getContext(‘2d‘);
- JS Creating an Image Object
let img = new Image;img.src = ‘./image.png‘; //图片路径img.onload = function(){} //加载成功后的执行函数,之后的代码就写在其中
- Create a two-dimensional array that stores picture pixel points
let coordinates = [];for(let i=0; i<200; i++){ coordinates[i] = [];}
- Gets the pixel point, that is, using the Getimagedata method.
0, 0); //将图片画如canvaslet data = ctxt.getImageData(0, 0, 350, 200).data;//读取整张图片的像素。
- Storing pixels in a two-dimensional array
Let x=0,y=0; //the rows and columns of the two-dimensional array, x: Column y: line for (Let I =0,len = data.length; i<len;i+=< Span class= "Hljs-number" >4) {Let red = Data[i],//red color deep green = Data[i+1],//green color deep blue = Data[i+2], //blue color depth alpha = Data[i+3]; Transparency //each pixel as a two-bit array expands if (' ${red} ${green} ${blue} ' = = = ' 210 227 199 ') {coordinates[y][x] = 0;} else{coordinates[y][x] = 1;} x + +, if (× >= 350) {x = 0; y++; }}
- The current code is as follows:
(function () {Let ctxt = Canvas.getcontext (' 2d '); Let img = new Image; let coordinates = []; Let H =Max, w =350; ForLet i=0; i<200; i++) {Coordinates[i] = []; } img.src = './image.png '; Picture Path img.onload = function () {Ctxt.drawimage (Img0,0); Let data = Ctxt.getimagedata (0,0,350, 200). data;//reads the pixels of the entire picture. Let x=0,y=0; for (let i =0,len = data.length; i<len;i+=4) {Let red = data[ i],//red dark green = data[i+1],//green dark blue = data[i+2],//blue color depth alpha = Data[i+3];//transparency//Put each pixel point, Expand if (' ${red} ${green} ${blue} ' = = = ' 227 199 ') as a two-bit array { COORDINATES[Y][X] = 0;} else{coordinates[y][x] = 1 X >= 350) {x = 0coordinates) ;}) ()
Image.png
constitutes a two-dimensional array similar to the following:
0,0,0,0,0,0,0,0,0,0,0,0
0,0,1,1,1,0,0,0,0,0,0,0
0,1,1,1,1,0,0,0,0,0,0,0
0,1,1,1,0,0,0,1,1,1,1,0
0,0,0,0,0,0,1,1,1,0,0,0
0,0,0,0,0,0,1,1,1,0,0,0
0,0,0,0,0,0,0,0,0,0,0,0
So we just need to know how many of these contiguous 1 blocks in a two-dimensional array will know how many shapes there are in the picture, and how many 1 are in the block, then the area of this block is 1.
Recursive backtracking algorithm
Calculates the contiguous area and number of const LINKSUM = (i,j,num) =>{Walk the road 0 coordinates[i][j] =0; num++;Up if ((i+1 < h) && coordinates[i+1] [j] = = 1) {num = linksum (i+1, J, num);} Down if ((J+1 < W) && Coordinates[i][j+1] = = 1) {num = Linksum (i, J+1, num);} //Left if ((I-1 >= 0) && Coordinates[i-1][j] = = 1) {num = Linksum (i -1, J, num); } //Right if ((J-1 >= 0) && Coordinates[i][j-1] = = 1) {num = Linksum (i, J-1, num); } return num;
Unfamiliar, direct Baidu is good, here is not much to say, in fact, the code reflects a lot of information.
Use the algorithm to count and calculate the results.
Const GETCOUNTANDAREA = () =>{let sum = [];LetCount =R; for (leti = 0; i < h; i++) //Traverse two-dimensional array { for (letj = 0; J < W; J + +) { //number of consecutive 1 if (c OORDINATES[I][J] = = 1) {let buf = 0; //number of consecutive 1 BUF = Linksum (I,J,BUF); count++; Total number of Sum.push ({index: count, //Shape area:buf //shape's Area});}} return { count, sum};}
The final code
(function () {Let ctxt = Canvas.getcontext (' 2d '); Let img = new Image; let coordinates = []; Let H =Max, w =350; ForLet i=0; i<200; i++) {Coordinates[i] = []; } img.src = './image.png '; Picture Path img.onload = function () {Ctxt.drawimage (Img0,0); Let data = Ctxt.getimagedata (0,0,350,). data;//reads the pixels of the entire picture. Let x=0,y=0; ForLet i =0,len = data.length; i<len;i+=4) {Let red = data[i],//red color deep green = data[i+1],//green dark blue = data[i+2],//blue Dark alpha = data[i+3];//transparency//put each pixel in the form of a two-bit array to expand if (' ${red} ${green} ${blue} ' = = = ' 210227199 ') {coordinates[y][x] =0; }else{Coordinates[y][x] =1; } x + +; IfX >={x =0; y++; }}//Console.log (coordinates); Let rst = Getcountandarea (); Console.log (Rst; Console.log (' Number: ' + rst.count '); ForLet i=0; i<rst.sum.length; i++) {Console.log (' ${i+1} of area: ${rst.sum[i].area} px '); }} const Getcountandarea = () =>{let sum = []; Let count =0; ForLet i =0; I < H; i++) {for (Let j =0; J < W; J + +) {//continuousThe number of 1 if (COORDINATES[I][J] = =1) {Let buf =0; BUF = Linksum (I,J,BUF); count++; Sum.push ({index:count, area:buf}); }}} return {count, sum}; }//calculates the contiguous area and number of const LINKSUM = (I,j,num) =>{//Walk on the road is placed0 Coordinates[i][j] =0; num++; Up if ((i+1 < h) && coordinates[i+1][j] = = 1) {num = Linksum (i+1, J, num) ;}//Down if ((j+1 < W) && Co Ordinates[i][j+1] = = 1) {num = linksum (i, j+1, num) ; }//Left if ((i-1 >= 0) && coordinates[i-1][j] = = 1) {num = linksum (i-1, J, num) ;}//Right if (j-1 >= 0) && coordinates[i][j-1] = = 1) { num = linksum (i, j-1, num) ;} return num;}) ()
Results of the operation:
You are welcome to join the Learning Exchange Group if you encounter any problems or want to acquire learning resources in the learning process.
343599877, we learn the front-end together!
An algorithmic problem in front-end interview