2011-04-17 166 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

您是否從另一個域中獲取圖像?如果是這樣,那麼這是一個安全錯誤:-)它被認爲是同樣的問題試圖搞砸裝載有來自另一個域的內容的'