4
private void button1_Click(object sender, EventArgs e)
{
    Bitmap im1 = new Bitmap(@"C:\Users\user\Downloads\CaptchaCollection\1.png");
    Bitmap im2 = new Bitmap(@"C:\Users\user\Downloads\CaptchaCollection\2.png");

    if (HashImage(im1) == HashImage(im2))
    {
        MessageBox.Show("Same Image");
    }

    else
    {
        MessageBox.Show("Different Image");
    }
}

If the button is clicked it will compare these 2 images.

Here is the code that is used to hash an image.

public byte[] HashImage(Bitmap image)
{
    var sha256 = SHA256.Create();

    var rect = new Rectangle(0, 0, image.Width, image.Height);
    var data = image.LockBits(rect, ImageLockMode.ReadOnly, image.PixelFormat);

    var dataPtr = data.Scan0;

    var totalBytes = (int)Math.Abs(data.Stride) * data.Height;
    var rawData = new byte[totalBytes];
    System.Runtime.InteropServices.Marshal.Copy(dataPtr, rawData, 0, totalBytes);

    image.UnlockBits(data);

    return sha256.ComputeHash(rawData);
}

So how do I use the HashImage() method to compare both those images if they're the same visually or not?

I tried comparing 2 images that are clearly the same but they aren't working to compare correctly. Instead I'm getting as if it's a different image.

I even tried this but it's not working either.

if (HashImage(im1).Equals(HashImage(im2)))

UPDATE: I've tried this but it isn't working either.

if (ReferenceEquals(HashImage(im1),HashImage(im2)))
puretppc
  • 3,232
  • 8
  • 38
  • 65
  • 1
    Should be if (HashImage(im1) == HashImage(im2)) ... – Inisheer Jan 28 '14 at 04:22
  • @JTA Oh my bad. Thanks for the correction. But the problem is, it's still not working properly because it's not comparing correctly. It's claiming it's different even though they are the same – puretppc Jan 28 '14 at 04:31
  • 1
    You should other approach for comapring arrays, see details here: http://stackoverflow.com/questions/713341/comparing-arrays-in-c-sharp – Tony Jan 28 '14 at 04:39
  • @Tony I tried `ReferenceEquals` but it's not really working :( Thanks for the tips though – puretppc Jan 28 '14 at 05:04
  • 2
    `ReferenceEquals` is wrong solution, I meant `Enumerable.SequenceEqual(a1, a2);` actually. – Tony Jan 28 '14 at 05:09

1 Answers1

4

I know 3 ways to compare byte array:

  • byte[].SequenceEqual(byte[])
  • System.Text.Encoding.UTF8.GetString(byte[]) ==
  • Convert.ToBase64String(byte[]) ==

For your code you can easy try this:

   Console.WriteLine("SEQUENCE EQUAL: " + (HashImage(im1).SequenceEqual(HashImage(im2)) ? "TRUE" : "FALSE") + " (easiest way)");
   Console.WriteLine("UTF8 STRING:    " + (System.Text.Encoding.UTF8.GetString(HashImage(im1)) == System.Text.Encoding.UTF8.GetString(HashImage(im2)) ? "TRUE" : "FALSE") + " (conversion to utf string - not good for display or hash, good only for data from UTF8 range)");
   Console.WriteLine("HASH STRING:    " + (Convert.ToBase64String(HashImage(im1)) == Convert.ToBase64String(HashImage(im2)) ? "TRUE" : "FALSE") + " (best to display)");

   Console.WriteLine("1: " + Convert.ToBase64String(HashImage(im1)));
   Console.WriteLine("2: " + Convert.ToBase64String(HashImage(im2)));

Add this to your code right after initialization of Bitmap im2, and look at results in output window. You can use any of this for compare and evaluate if array is the same.

Note: System.Text.Encoding.UTF8.GetString is not suitable for use in this case (hash data from picture). See comment from @CodesInChaos below.

Atiris
  • 2,613
  • 2
  • 28
  • 42
  • 1
    The second one only works if the bytes are UTF-8 encoded text, which hashes are not. A sane implementation would throw an exception on invalid input, unfortunately the default implementation in .net silently corrupts the data instead. For example `Encoding.UTF8.GetString(new byte[]{0xFF}) == Encoding.UTF8.GetString(new byte[]{0x80})`. – CodesInChaos Jan 29 '14 at 22:56
  • Good point, thanks, I include comment about this into my answer. – Atiris Jan 29 '14 at 23:08
  • Converting to string is never a good way to compare byte arrays. Never. – Nyerguds Sep 05 '17 at 13:55