![](/img/trans.png)
[英]Difference between “Coordinates in pixels” and “Coordinates” in Canvas HTML
[英]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.