簡體   English   中英

畫布像素進行坐標

[英]Canvas pixels to coordinates

我有一塊width = 900, height = 574的畫布。 我有畫布的所有像素。 畫布內有一些矩形,知道矩形的所有像素后,我想要找到的是矩形的4個點的坐標,然后找到矩形的寬度和高度。

在此處輸入圖片說明

所以我所做的是:

  pMinX = (_.min(points)/ 4) % highlightCanvas.width
  pMinY = Math.floor((_.min(points) / 4) / highlightCanvas.width)
  pMaxX = (_.max(points) / 4) % highlightCanvas.width
  pMaxY = Math.floor((_.max(points) / 4) / highlightCanvas.width)

Points是要查找其坐標的矩形的像素(4通道rgba)數組。

pMinY和pMaxY似乎工作良好,而pMinX,pMaX有時似乎正確,而其他錯誤。 為了進行測試,我創建了一個浮動div並根據以下內容調整其大小:

  {
    width:  pMaxX - pMinX
    height: pMaxY - pMinY
  }

div的高度始終正確。 但是寬度有時會失敗。 知道為什么有時計算會失敗嗎?

這是帶注釋的代碼,顯示了如何計算圖像中鮭魚色矩形的邊界框(x,y,寬度,高度)。

在此處輸入圖片說明

它是這樣的:

  • 使用.getImageData獲取畫布上每個像素的r,g,b,a值。

  • 設置一個像素的rgba必須滿足的測試,才能將其視為“在所需矩形內”。在您的示例中,鮭魚矩形由2種顏色組成,因此此測試將捕獲矩形內的所有像素:

     // create an array to hold tests that are used to // find your desired pixels. The tests should be functions // that return true for your desired rgba pixel values // (substitue whatever algorithm test that are necessary for your design) var tests=[]; // add a test into the tests[] array tests.push(function(r,g,b,a){ return( (r==251 && g==115 && b==119)|| (r==249 && g==100 && b==107) ); }); 
  • 確定滿足測試要求的像素的minX,minY,maxX和maxY

  • 根據確定的最小值和最大值計算矩形像素的邊界框:

     var bounds={ x:minX, y:minY, width:maxX-minX, height:maxY-minY }; 

重要說明:若要允許.getImageData,您必須滿足安全性限制。 通常的方法是在與您的網頁相同的域中提供圖片。 或者,您可以設置托管圖像的服務器,以將該圖像提供給任何匿名請求者。

示例代碼和演示:

 // canvas related variables var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; // load the image var img=new Image(); // the image must satisfy cross-origin restrictions // or else we can't use .getImageData img.crossOrigin='anonymous'; img.onload=start; img.src="https://dl.dropboxusercontent.com/u/139992952/multple/findRect.png"; function start(){ // resize the canvas to the image size // and draw the image onto the canvas cw=canvas.width=img.width; ch=canvas.height=img.height; ctx.drawImage(img,0,0); // create an array to hold tests that are used to // find your desired pixels. The tests should be functions // that return true for your desired rgba pixel values // (substitue whatever algorithm test that are necessary for // your design) var tests=[]; // sample test returns true if matching the 2 colors making up the rect tests.push(function(r,g,b,a){ return( (r==251 && g==115 && b==119)|| (r==249 && g==100 && b==107) ); }); // find the bounds of all pixels meeting the prescribed test(s) var bounds=findImageBounds(tests); // testing...draw just the discovered rect to a second canvas var c=document.createElement('canvas'); var cctx=c.getContext('2d'); document.body.appendChild(c); c.width=cw; c.height=ch; cctx.drawImage(canvas, bounds.x,bounds.y,bounds.w,bounds.h, bounds.x,bounds.y,bounds.w,bounds.h ); } function findImageBounds(tests){ // get the rgba color values for all pixels on the canvas var d=ctx.getImageData(0,0,cw,ch).data; // iterate over each pixel // find the min/max X,Y of pixels where all tests are true var minX=1000000; var minY=1000000; var maxX=-1000000; var maxY=-1000000; var hits=0; for(var y=0;y<ch;y++){ for(var x=0;x<cw;x++){ // n==the position in the rgba array for canvas position x,y n=(y*cw+x)*4; // the rgba values at this pixel r=d[n]; g=d[n+1]; b=d[n+2]; a=d[n+3]; // run all tests on this pixel var testsTrue=true; for(var i=0;i<tests.length;i++){ testsTrue=testsTrue && tests[i](r,g,b,a); } // if this pixel meets all tests // see if it influences our boundary if(testsTrue){ hits++; if(x<minX){minX=x;} if(y<minY){minY=y;} if(x>minX){maxX=x;} if(y>maxY){maxY=y;} } }} // return the x,y,width,height of the bounding box // of pixels meeting all the supplied tests return({x:minX,y:minY,w:maxX-minX,h:maxY-minY,pixelCount:hits}); } 
 body{ background-color: ivory; } canvas{border:1px solid red;} 
 <h4>The original canvas</h4> <canvas id="canvas" width=300 height=300></canvas> <h4>Just the rect from the canvas</h4> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM