2011-04-17 167 views
7

我一直在试图制作一个脚本来比较HTML5和Javascript中的两个图像。但出于某种奇怪的原因,它总是返回图像完全相同。getImageData总是返回0

当我们看看问题会发生什么时,我发现每个像素的每个数据值由于某种奇怪的原因返回“0”。

那么,有什么想法我做错了什么? :)

出于某种原因,我觉得这是非常简单的事情,但我刚刚了解了画布元素,所以是的。

这是我的代码:

function compareImg() { 
    var c1 = document.getElementById("c"); 
    var ctx1 = c1.getContext("2d"); 
    var c2 = document.getElementById("c2"); 
    var ctx2 = c2.getContext("2d"); 

    var match = 0; 

    var img1 = new Image(); 
    img1.src = "cat.jpg"; 
    img1.onload = function() { 
     ctx1.drawImage(img1, 0, 0); 
    } 
    var img2 = new Image(); 
    img2.src = "bird.jpg"; 
    img2.onload = function() { 
     ctx2.drawImage(img2, 0, 0); 
    } 


    for(var x = 0; x<c1.width; x++) { // For each x value 
     for(var y = 0; y<c1.height; y++) { // For each y value 
      var data1 = ctx1.getImageData(x, y, 1, 1); 
      var data2 = ctx2.getImageData(x, y, 1, 1); 
      if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) { 
       match++; 
      } 
     } 
    } 
    var pixels = c1.width*c1.height; 
    match = match/pixels*100; 
    document.getElementById("match").innerHTML = match + "%"; 
} 

回答

5

在进行比较之前,您并未等到图像加载并绘制完成。试试这个:

var img = new Image; 
img.onload = function(){ 
    ctx1.drawImage(img,0,0); 
    var img = new Image; 
    img.onload = function(){ 
    ctx2.drawImage(img,0,0); 
    // diff them here 
    }; 
    img.src = 'cat.jpg'; 
}; 
img.src = 'cat.jpg'; 

如上所示,你应该总是set your srcafter your onload

+0

感谢您回应我关于分配”src“和”onload“顺序的迷信。 :-)也许这毕竟不是迷信! – Pointy 2011-04-17 16:13:03

+0

@Pointy [不,它不只是迷信。](http://stackoverflow.com/questions/4776670/should-setting-an-image-src-to-dataurl-be-available-immediately) – Phrogz 2011-04-17 16:17:23

+0

迷人,@ Phrogz!我觉得所有这些年来都在告诉人们这样做: - ) – Pointy 2011-04-17 16:22:25

1

我怀疑问题是,你的图像数据可能是不准备在您尝试使用它在画布点。如果你的代码推迟到onload事件处理程序,这将(可能)帮助:

var img1 = new Image(), count = 2; 
img1.src = "cat.jpg"; 
img1.onload = function() { 
    ctx1.drawImage(img1, 0, 0); 
    checkReadiness(); 
} 
var img2 = new Image(); 
img2.src = "bird.jpg"; 
img2.onload = function() { 
    ctx2.drawImage(img2, 0, 0); 
    checkReadiness(); 
} 

function checkReadiness() { 
    if (--count !== 0) return; 

    for(var x = 0; x<c1.width; x++) { // For each x value 
    for(var y = 0; y<c1.height; y++) { // For each y value 
     var data1 = ctx1.getImageData(x, y, 1, 1); 
     var data2 = ctx2.getImageData(x, y, 1, 1); 
     if (data1.data[0] == data2.data[0] && data1.data[1] == data2.data[1] && data1.data[2] == data2.data[2]) { 
      match++; 
     } 
    } 
    } 
    var pixels = c1.width*c1.height; 
    match = match/pixels*100; 
    document.getElementById("match").innerHTML = match + "%"; 
} 

我所做的只是周围添加代码的函数封装。该函数检查我添加的图像计数变量,并且仅当它为零时(即,仅在两个图像已经加载之后)才能完成这项工作。我设置了“src”属性,我有这个想法,也许只有在过去,浏览器可能无法运行处理程序如果if(if)图像已经在缓存中)。

现在另一件事:您可能应该只获取一次图像数据,然后迭代返回的数据。为每个像素调用“getImageData()”对于浏览器来说都是很多工作。

+0

现在,我在脚本获取图像数据的第一行发生“安全错误”...... Chrome显示“SECURITY_ERR:DOM异常18”,Firefox显示“错误:未捕获的异常:[异常... “安全错误”代码:“1000”nsresult:“0x805303e8(NS_ERROR_DOM_SECURITY_ERR)...]” – iamarcel 2011-04-17 16:19:08

+1

您是否从另一个域中获取图像?如果是这样,那么这是一个安全错误:-)它被认为是同样的问题试图搞砸装载有来自另一个域的内容的'