How do I compare if 2 images are the same using Ha

2019-02-23 17:02发布

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)))

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-02-23 17:41

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.

查看更多
登录 后发表回答