3
\$\begingroup\$

I am using the following code to compare 2 images:

HTML (for example use only):

<canvas id="gViewCanvas"></canvas>
<img id="image1" src="image1.png" />
<img id="image2" src="image2.png" />

Javascript:

var gOldImage = document.getElementById("image1");
var gScreenImage = document.getElementById("image2");

var gViewCanvas = document.getElementById("gViewCanvas");
var gViewContext = gViewCanvas.getContext('2d');

var gGridSizeX = 1920;
var gGridSizeY = 32;
var nrX = Math.round(1920 / gGridSizeX);
var nrY = Math.round(955 / gGridSizeY);
gPixelCount = (gGridSizeX * gGridSizeY) * 4;




 function compareImages(img1, img2, pixelCount) {
   for (var i = 0; i < pixelCount; ++i) {
      if (img1.data[i] !== img2.data[i]) {
           return false;
        }
   }
   return true;
}



  var data, data2, BMPData, xpos, ypos, encoded, y, x;
//Iterate through lines of the image (width x 32)
  for (y = 0; y < nrY; y++) {
    for (x = 0; x < nrX; x++) {

      xpos = x * gGridSizeX;
      ypos = y * gGridSizeY;
      //draw both sextions of images to the canvas and store pixel data in variables: data and data2
      gViewContext.drawImage(gOldImage, xpos, ypos, gGridSizeX, gGridSizeY, 0, 0, gGridSizeX, gGridSizeY);
      data = gViewContext.getImageData(0, 0, gGridSizeX, gGridSizeY);

      gViewContext.drawImage(gScreenImage, xpos, ypos, gGridSizeX, gGridSizeY, 0, 0, gGridSizeX, gGridSizeY);
      data2 = gViewContext.getImageData(0, 0, gGridSizeX, gGridSizeY);

      if (!compareImages(data, data2, gPixelCount)) {

        console.log("images are different");

      }else{
         console.log("same");             
      }
    }
  }

​ I am looking for any speed increases possible please.

I have already tested things such as:

  • Methods of getting data from the canvas (toDataURL etc)
  • different grid sizes (width * X is the faster than 32x32 etc)
  • Drawing each image onto the canvas only once rather that inside the for loop (takes longer as canvas is bigger)

Any obvious things i've missed?

\$\endgroup\$
2
  • 1
    \$\begingroup\$ FYI, If you draw an image on a canvas from a different domain than your own, you can't use getImageData. In short, this code will not work if you change image1.png to http://www.google.com/logo.png (unless this script were to be run from www.google.com) \$\endgroup\$ Commented Aug 23, 2012 at 14:31
  • \$\begingroup\$ Yep thanks. In reality, I am actually getting a DataURL from a chrome extension, but the principal is the same :) \$\endgroup\$ Commented Aug 23, 2012 at 14:54

1 Answer 1

5
\$\begingroup\$

Instead of redrawing and getting new data for every pixel, just draw once and get both data arrays. Next loop through them and check their values:

var c1 = document.getElementById('c1');
var c2 = document.getElementById('c2');
ctx1 = c1.getContext('2d');
ctx2 = c2.getContext('2d');

ctx1.fillRect(10, 10, 280, 280);
ctx2.fillRect(10, 10, 280, 280);

var data1 = ctx1.getImageData(0, 0, c1.width, c1.height).data;
var data2 = ctx2.getImageData(0, 0, c2.width, c2.height).data;

var same = true;

for (var i = 0; i < data1.length; i++) {
    if (data1[i] !== data2[i]) {
        same = false;
        break;
    }
}

Fiddle here: http://jsfiddle.net/SBDfz/1/

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.