3

I have 2 imageData objects which I get from the same canvas through the same context. But when comparing them, they are not equal when I would think they would be as they should contain the same data:

var canv = document.createElement("canvas");
canv.setAttribute('width', 300);
canv.setAttribute('height', 300);
var context = canv.getContext('2d');
context.fillStyle = "#ff0000";
context.fillRect(0, 0, 300, 300);

var imageData = context.getImageData(0, 0, 300, 300);
var imageData2 = context.getImageData(0, 0, 300, 300);

if (imageData == imageData2) {
    console.log("Test1: same");
} else {
    console.log("Test1: different");
}
if (imageData.data == imageData2.data) {
    console.log("Test2: same");
} else {
    console.log("Test2: different");
}

if (imageData == imageData) {
    console.log("Test3: same");
} else {
    console.log("Test3: different");
}
if (imageData.data == imageData.data) {
    console.log("Test4: same");
} else {
    console.log("Test4: different");
}​

This code outputs:

Test1: different
Test2: different
Test3: same
Test4: same 

So comparing the object to itself works as expected and when comparing the data inside the imageData object, but not against what should be an identical copy.

Is this an issue with comparing objects or is there something I am missing with the way the data is being sourced from the canvas element?

Thanks

Andrew Hall
  • 3,058
  • 21
  • 30

3 Answers3

4

imageData.data is a CanvasPixelArray, which is an object. For two objects A and B A == B will only be true if they reference the same object.

Since you're using two different imageData objects both imageData == imageData2 and imageData.data == imageData2.data will evaluate to false, even if their properties are the same.

Note that the type of imageData.data has been changed to Uint8ClampedArray, which is basically a Canvas Pixel ArrayBuffer.

In order to check two Images you would have to do a pixel-based check:

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

However, there could be already a library which uses non-blocking methods.

aeronaut
  • 53
  • 1
  • 7
Zeta
  • 103,620
  • 13
  • 194
  • 236
  • Thanks for the reply. Can you suggest a better way of comparing these 2 objects then? – Andrew Hall Aug 01 '12 at 08:09
  • Posted the most trivial solution I could think of - it won't be fast, but it should work. Maybe there are some libraries for this. – Zeta Aug 01 '12 at 08:15
2

How to convert image into base64 string using javascript

Read this question about converting image to base64,

Made you could convert it to base 64 strings and compare the strings?

Trying having a look here : http://www.webresourcesdepot.com/pixel-by-pixel-image-comparison-with-im-js/

http://tcorral.github.com/IM.js/

Which i've used for detecting duplicate images, maybe this is what your looking for?

Community
  • 1
  • 1
Lemex
  • 3,772
  • 14
  • 53
  • 87
0
JSON.stringify(imageData) == JSON.stringify(imageData2)

should work as expected but it's a little slow with large images

Indiana Kernick
  • 5,041
  • 2
  • 20
  • 50