我有一个画布,用户可以在其中写东西,并显示以前保存的图纸。但是由于某些因素,我们检测到其中一些没有使用总画布区域。所以我的问题是:
感谢。
答案 0 :(得分:2)
我可以检测用户绘制的区域并使其变大 粉碎了美国帆布空间?
通过使用短语“撕碎未绘制的空间”,我假设您想要缩放现有图像以填充所有画布区域。
是的,你可以......
<强>步骤#1 强>
您可以使用getImageData
从画布中获取像素颜色数据。此数据是一个数组,包含画布上每个像素的红色,绿色,蓝色和Alpha值。
var pixelData=mainContext.getImageData(0,0,mainCanvas.width,mainCanvas.height).data;
画布像素[0,0]的数据:
画布像素[1,0]的数据:
使用像素数据确定用户不透明像素的边界框。您可以通过确定alpha> 250的最顶部,最左侧,最底部和最右侧像素来执行此操作。
var boundLeft,boundTop,boundRight,boundBottom,boundWidth,boundHeight;
function getBounds(){
boundLeft=1000000;
boundTop=1000000;
boundRight=-1000000;
boundBottom=-1000000;
//
var d=ctx.getImageData(0,0,cw,ch).data;
//
for(var i=0;i<d.length;i+=4){
// test the alpha (d[i+3])
if(d[i+3]>250){
var px=parseInt(i/4);
var pixelY=parseInt(px/cw);
var pixelX=px-pixelY*cw;
if(pixelX<boundLeft){boundLeft=pixelX;}
if(pixelX>boundRight){boundRight=pixelX;}
if(pixelY<boundTop){boundTop=pixelY;}
if(pixelY>boundBottom){boundBottom=pixelY;}
boundWidth=boundRight-boundLeft;
boundHeight=boundBottom-boundTop;
}
}
}
<强>步骤#2 强>
创建一个与边界框大小相同的内存中画布。
var memCanvas=document.createElement('canvas');
var memContext=memCanvas.getContext('2d');
memCanvas.width=boundWidth;
memCanvas.height=boundHeight;
<强>步骤#3 强>
使用context.drawImage
的剪辑版本将主画布的边界区域绘制到内存中的画布。
memContext.drawImage(mainCanvas,
// grab the "used" pixels from the main canvas
boundLeft,boundTop,boundWidth,boundHeight,
// and draw those pixels on the in-memory canvas
0,0,boundWidth,boundHeight
);
<强>步骤#4 强>
(可选择将主画布调整为边界框大小)
mainCanvas.width=boundWidth;
mainCanvas.height=boundHeight;
将内存中的画布绘制到主画布上
mainContext.clearRect(0,0,mainCanvas.width,mainCanvas.height);
mainContext.drawImage(memCanvas,0,0);
我可以检测用户是使用完整的画布区域还是说 超过60%吗?如果有,怎么样?这样我就可以发出警告了 用户。
是的,你可以......
使用上面相同的技术计算boundWidth&amp; boundHeight
然后,您可以使用边界框大小与画布大小的比率计算“已使用”画布的百分比:
var percent = (boundWidth*boundHeight) / (mainCanvas.width*mainCanvas.height);
在用户添加到绘图时计算新的边界框
在用户绘制每个新像素之后,不是使用getImageData
计算新的边界框,而是在新像素超出现有边界时扩展边界框:
if(newPixelX<leftmost){boundLeft=newPixelX;}
if(newPixelX>rightmost){boundRight=newPixelX;}
if(newPixelY<topmost){boundTop=newPixelY;}
if(newPpixelY>bottommost){boundBottom=newPixelY;}
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
var isDown=false;
var startX,startY;
var leftmost,topmost,rightmost,bottommost;
// load image
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/car.png";
function start(){
//
cw=canvas.width=img.width;
ch=canvas.height=img.height;
//
ctx.drawImage(img,0,0);
//
getBounds();
}
function getBounds(){
leftmost=1000000;
topmost=1000000;
rightmost=-1000000;
bottommost=-1000000;
//
var d=ctx.getImageData(0,0,cw,ch).data;
//
for(var i=0;i<d.length;i+=4){
// test the alpha (d[i+3])
if(d[i+3]>250){
var px=parseInt(i/4);
var pixelY=parseInt(px/cw);
var pixelX=px-pixelY*cw;
if(pixelX<leftmost){leftmost=pixelX;}
if(pixelX>rightmost){rightmost=pixelX;}
if(pixelY<topmost){topmost=pixelY;}
if(pixelY>bottommost){bottommost=pixelY;}
}
}
}
function highlightBounds(){
var previousFill=ctx.fillStyle;
ctx.globalAlpha=0.05;
ctx.fillStyle='red';
ctx.fillRect(leftmost,topmost,(rightmost-leftmost),(bottommost-topmost));
ctx.globalAlpha=1.00;
ctx.fillStyle=previousFill;
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
isDown=true;
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseup stuff here
isDown=false;
}
function handleMouseOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseOut stuff here
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
ctx.beginPath();
ctx.arc(mouseX,mouseY,3,0,Math.PI*2);
ctx.closePath();
ctx.fill();
if(mouseX<leftmost){leftmost=mouseX;}
if(mouseX>rightmost){rightmost=mouseX;}
if(mouseY<topmost){topmost=mouseY;}
if(mouseY>bottommost){bottommost=mouseY;}
var boundsArea=(rightmost-leftmost)*(bottommost-topmost);
var canvasArea=cw*ch;
$pct.text(parseInt(boundsArea/canvasArea*100)+'% of canvas area is used');
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
var $pct=$('#pct');
$('#shred').click(function(){
var width=rightmost-leftmost;
var height=bottommost-topmost;
var memCanvas=document.createElement('canvas');
var memContext=memCanvas.getContext('2d');
memCanvas.width=width;
memCanvas.height=height;
memContext.drawImage(canvas,
// grab the "used" pixels from the main canvas
leftmost,topmost,width,height,
// and draw those pixels on the in-memory canvas
0,0,width,height
);
canvas.width=width;
canvas.height=height;
ctx.drawImage(memCanvas,0,0);
});
body{ background-color: white; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id=shred>Eliminate outside space</button>
<h4 id=pct>Drag mouse</h4>
<canvas id="canvas" width=300 height=300></canvas>