Javascript画布:如何有效地计算两个画布的距离
Javascript canvas: how to efficiently compute distance of two canvases
我想计算两个画布中绘制的两个图形之间的距离,实际上我正在做以下操作,迭代画布的数据(画布大小相同):
var computeDifference = function() {
var imgd1 = bufferCtx.getImageData(0, 0, w, h).data;
var imgd2 = targetCtx.getImageData(0, 0, w, h).data;
var diff = 0;
for(var i=0; i<imgd1.length; i+=4) {
var d = (imgd1[i]-imgd2[i]);
var tot = d > 0 ? d : -d;
diff += tot
}
return diff;
}
这不是很有效。
有更好的方法吗?我读过关于复合运算的文章,但我不确定这在这种情况下是否有帮助。
我特意只考虑R频道,因为目前我使用的是黑白图像,但我稍后可能会考虑其他频道。
您可以在单个画布上使用新的difference
混合方法,在上次绘制之前设置的模式下绘制两个图像,然后提取位图数据以获得总和。
可以使用相同的属性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
}
现场性能测试
测试1将进行手动差异计算,测试2将使用浏览器差异混合模式。在我的设置中,FireFox以超过4倍的优势获胜(Chrome中的差异稍小)。
var canvas1 = document.createElement("canvas"),
canvas2 = document.createElement("canvas"),
ctx1 = canvas1.getContext("2d"),
ctx2 = canvas2.getContext("2d"),
img1 = new Image, img2 = new Image,
count = 2,
startTime1, startTime2, endTime1, endTime2, sum1, sum2;
performance = performance || Date; // "polyfill" the performance object
img1.crossOrigin = img2.crossOrigin = ""; // we need to extract pixels
img1.onload = img2.onload = loader;
img1.src = "http://i.imgur.com/TJiD5GM.jpg";
img2.src = "http://i.imgur.com/s9ksOb1.jpg";
function loader() {if(!--count) test1()} // handle async load
function test1(){
startTime1 = performance.now();
ctx1.drawImage(img1, 0, 0);
ctx2.drawImage(img2, 0, 0);
var data1 = ctx1.getImageData(0, 0, 500, 500).data,
data2 = ctx2.getImageData(0, 0, 500, 500).data,
i = 0, len = data1.length, sum = 0;
// we do all channels except alpha channel (not used in difference calcs.)
while(i < len) {
sum += Math.abs(data2[i] - data1[i++]) +
Math.abs(data2[i] - data1[i++]) +
Math.abs(data2[i] - data1[i++]);
i++
}
sum1 = sum;
endTime1 = performance.now();
test2();
}
function test2(){
startTime2 = performance.now();
ctx1.drawImage(img1, 0, 0);
ctx1.globalCompositeOperation = "difference";
if (ctx1.globalCompositeOperation !== "difference")
alert("Sorry, use Firefox or Chrome");
ctx1.drawImage(img2, 0, 0);
var data = ctx1.getImageData(0, 0, 500, 500).data,
i = 0, len = data.length, sum = 0;
// we do all channels except alpha channel
while(i < len) {
sum += data[i++];
sum += data[i++];
sum += data[i++];
i++;
}
sum2 = sum;
endTime2 = performance.now();
result();
}
function result() {
var time1 = endTime1 - startTime1,
time2 = endTime2 - startTime2,
factor = time1 / time2,
res = "Manual method: " + time1.toFixed(3) + "ms<br>";
res += "Blending mode: " + time2.toFixed(3) + "ms<br>";
res += "Factor: " + factor.toFixed(2) + "x<br>";
res += "Sum 1 = " + sum1;
res += "<br>Sum 2 = " + sum2;
document.querySelector("output").innerHTML = res;
}
<output>Loading images and calculating...</output>
相关文章:
- 查找与通过两次调用地理编码创建的两个 latlng 对象的距离
- Javascript画布:如何有效地计算两个画布的距离
- javascript中两个位置之间的距离
- 使用javascript计算两个邮政编码之间的距离
- 如何确定两个凹/凸形状是否处于特定距离
- 如何计算两个纬度和经度之间的距离
- DOM 中两个元素之间的距离(以 px 为单位)
- 如果两个元素之间的距离小于 X,则执行 Y
- Javascript - 求两个数字之间的距离
- 获取两个位置之间的距离和时间的功能
- 两个位置之间的距离 - 谷歌地图
- 有没有可能比平方距离算法更快地测试两个圆的交点
- JavaScript:定义两个类之间的距离
- javascript中两个画布坐标之间的距离
- Parse.com云代码,计算两个位置之间的行驶距离
- 如何在php中计算两个地方之间的行驶距离以及地图
- 有没有办法找出两个键盘键之间的距离
- 如何计算两个元素之间的距离,像这样
- 如何在谷歌地图上获取性别数字,并计算两个性别数字之间的距离
- ajax post请求调用时,为什么函数计算两个元素之间的距离不起作用