Javascript画布:如何高效地计算两个画布的距离

Javascript画布:如何高效地计算两个画布的距离,javascript,canvas,Javascript,Canvas,我想计算在两张画布上绘制的两个图形之间的距离,实际上我在做以下工作,迭代画布的数据(画布大小相同): var computeDifference=function(){ var imgd1=bufferCtx.getImageData(0,0,w,h).data; var imgd2=targetCtx.getImageData(0,0,w,h).data; var-diff=0; 对于(VarI=0;I0?d:-d; diff+=tot } 返回差; } 这不是很有效 有更好的方法吗?我读过

我想计算在两张画布上绘制的两个图形之间的距离,实际上我在做以下工作,迭代画布的数据(画布大小相同):

var computeDifference=function(){
var imgd1=bufferCtx.getImageData(0,0,w,h).data;
var imgd2=targetCtx.getImageData(0,0,w,h).data;
var-diff=0;
对于(VarI=0;I0?d:-d;
diff+=tot
}
返回差;
}
这不是很有效

有更好的方法吗?我读过关于复合操作的书,但我不确定这在这种情况下是否有帮助


我故意只考虑R通道,因为现在我正在用黑白图像操作,但是我可能稍后会考虑其他的通道。

< P>你可以在一个画布上使用新的<代码>差异< /COD>混合方法,在最后一次绘制之前用模式设置两个图像,然后提取位图数据以获得总数

您可以使用相同的属性
globalCompositeOperation
,设置混合模式

通过这种方式,您可以让浏览器计算每个组件上的差异,而只需对其进行汇总。您还可以保存一个画布,一次调用
getImageData()
,这在硬件加速系统上相对昂贵:

ctx.drawImage(image1, x, y);
ctx.globalCompositeOperation = "difference";  // use composite to set blending...
ctx.drawImage(image2, x, y);

// extract data, and sum -
注意:IE11不支持新的混合模式。对于IE,您需要像最初一样手动进行差异计算

您可以通过提供支持时的快速方法和不支持时的手动方法来检测此功能:

ctx.globalCompositeOperation = "difference";
if (ctx.globalCompositeOperation === "difference") {
    // fast
}
else {
    // manual
}
现场性能测试 Test1将进行手动差异计算,test2将使用浏览器差异混合模式。在我的设置中,FireFox以超过4倍的因数(略低于Chrome的差异)获胜

var canvas1=document.createElement(“canvas”),
canvas2=document.createElement(“canvas”),
ctx1=canvas1.getContext(“2d”),
ctx2=canvas2.getContext(“2d”),
img1=新图像,img2=新图像,
计数=2,
startTime1,startTime2,endTime1,endTime2,sum1,sum2;
性能=性能| |日期;/“polyfill”性能对象
img1.crossOrigin=img2.crossOrigin=“”;//我们需要提取像素
img1.onload=img2.onload=loader;
img1.src=”http://i.imgur.com/TJiD5GM.jpg";
img2.src=”http://i.imgur.com/s9ksOb1.jpg";
函数加载器(){if(!--count)test1()}//处理异步加载
函数test1(){
startTime1=performance.now();
ctx1.drawImage(img1,0,0);
ctx2.drawImage(img2,0,0);
var data1=ctx1.getImageData(0,0500500).data,
data2=ctx2.getImageData(0,0500500).data,
i=0,len=data1.length,sum=0;
//除alpha通道(不用于差分计算)外,我们处理所有通道
而(我”;
res+=“混合模式:”+time2.toFixed(3)+“ms
”; res+=“Factor:”+Factor.toFixed(2)+“x
”; res+=“总和1=”+sum1; res+=”
Sum 2=“+sum2; document.querySelector(“输出”).innerHTML=res; }

加载图像并计算…
谢谢,我不知道合成操作的不同。这稍微加快了我的代码速度。使用chrome进行分析显示drawImage()和getImageData()“现在是瓶颈。@Danielnick89是的,不幸的是,没有办法解决这些问题。根据您需要结果的准确性,您可以在获取数据之前将图像预缩放到较小的大小。它们仍然可能是瓶颈,但至少数据会更快到达。
ctx.globalCompositeOperation = "difference";
if (ctx.globalCompositeOperation === "difference") {
    // fast
}
else {
    // manual
}