GetImageData always returns 0

I am trying to make a script that compares two images in HTML5 and Javascript. But for some odd reason, it always returns that the images are exactly the same.

And when we look at the problem, I found that each data value of each pixel was being returned for some odd reason, "0".

So, any idea on what I did wrong? :)

For some reason, I feel this is something very simple, but I just found out about the canvas element, so yes.

This is my code:

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 + "%"; } 
+7
source share
2 answers

You do not wait until your images have loaded and drawn before performing the comparison. Try the following:

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

As shown above, you should always install src after onload .

+5
source

I suspect the problem is that your image data is probably not ready for what you are trying to use for the canvas. If you put this code aside on onload handlers, this will help (possibly):

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

All I did was add a function wrapper around your code. This function checks the variable of the number of images that I added, and only when it is equal to zero (i.e. only after loading both images), it will do the job.

(This may be superstition, but I always assign an β€œonload” handler before setting the β€œsrc” attribute. I have this idea that, perhaps, only in the past, browsers may not start the handler if the image is already in the cache.)

Now one more thing: you probably should just get the image data once, and then iterate over the returned data. Calling "getImageData ()" for each individual pixel will be a great job for the browser.

+1
source

All Articles