HiveBrain v1.2.0
Get Started
← Back to all entries
principlejavascriptMinor

Compare 2 Images

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
imagescomparestackoverflow

Problem

I am using the following code to compare 2 images:

HTML (for example use only):



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?

Solution

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/

Code Snippets

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

Context

StackExchange Code Review Q#14984, answer score: 5

Revisions (0)

No revisions yet.