2011-04-17 43 views
7

He estado tratando de hacer un script que compare dos imágenes en HTML5 y Javascript. Pero por alguna extraña razón, siempre regresa que las imágenes son completamente iguales.getImageData siempre devolviendo 0

Y al ver cuál podría ser el problema, descubrí que cada valor de datos de cada píxel devuelto, por alguna extraña razón, "0".

¿Alguna idea de lo que hice mal? :)

Por alguna razón, siento que es algo muy simple, pero acabo de enterarme del elemento del lienzo, así que sí.

Este es mi código:

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 + "%"; 
} 

Respuesta

5

No espere hasta que sus imágenes se hayan cargado y dibujado antes de realizar su comparación. Prueba esto:

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'; 

Como se muestra arriba, siempre se debe set your srcafter your onload.

+0

Gracias por hacerme eco de mi superstición sobre el orden de asignar" src "y" onload ". :-) ¡Tal vez no sea una superstición después de todo! – Pointy

+0

@Pointy [No, no es solo una superstición.] (Http://stackoverflow.com/questions/4776670/should-setting-an-image-src-to-dataurl-be-available-immediately) – Phrogz

+0

Fascinante, @ Phrogz! Me siento justificado por todos estos años diciéndole a la gente que haga eso :-) – Pointy

1

Sospecho que el problema es que los datos de imagen no es probable que esté listo en el punto que intenta utilizarlo para el lienzo. Si pospone ese código para los manipuladores onload, que (probablemente) ayuda:

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 + "%"; 
} 

único que hice fue agregar una función envoltorio alrededor de su código. Esa función verifica la variable de recuento de imágenes que agregué, y solo cuando es cero (es decir, solo después de que ambas imágenes se hayan cargado) hará el trabajo.

(Esta puede ser la superstición, pero siempre me asigno la "onload" manejador antes fijo el atributo "src". Tengo la idea de que, tal vez sólo en el pasado, los navegadores pueden fallar para ejecutar el manejador, si la imagen ya está en la memoria caché.)

Ahora, otra cosa: probablemente solo deba obtener los datos de la imagen una vez, y luego iterar sobre los datos devueltos. Llamar a "getImageData()" para cada píxel va a ser mucho trabajo para el navegador.

+0

Ahora recibo un "error de seguridad" en la primera línea donde el script obtiene los datos de la imagen ... Chrome dice "SECURITY_ERR: DOM exception 18" y Firefox dice "Error: excepción no detectada: [Excepción ... Código de "error de seguridad": "1000" nsresult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR) ...]" – iamarcel

+1

¿Está buscando las imágenes de otro dominio? Si es así, es un error de seguridad :-) Se considera el mismo tipo de problema que tratando de meterse con un '