【问题标题】:How do I compare if 2 images are the same using Hash bytes?如何使用哈希字节比较 2 个图像是否相同?
【发布时间】:2014-01-28 04:19:26
【问题描述】:
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");
    }
}

如果单击按钮,它将比较这两个图像。

这是用于散列图像的代码。

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

那么我如何使用HashImage() 方法来比较这两个图像,如果它们在视觉上是相同的呢?

我尝试比较 2 张明显相同但无法正确比较的图像。相反,我觉得这是一张不同的图片。

我什至试过这个,但它也不起作用。

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

更新:我已经尝试过了,但它也不起作用。

if (ReferenceEquals(HashImage(im1),HashImage(im2)))

【问题讨论】:

  • 应该是 if (HashImage(im1) == HashImage(im2)) ...
  • @JTA 哦,我的错。感谢您的更正。但问题是,它仍然无法正常工作,因为它没有正确比较。它声称它是不同的,即使它们是相同的
  • 您应该使用其他方法来处理数组,请在此处查看详细信息:stackoverflow.com/questions/713341/comparing-arrays-in-c-sharp
  • @Tony 我试过ReferenceEquals,但它并没有真正起作用:(尽管感谢您的提示
  • ReferenceEquals 是错误的解决方案,我的意思是 Enumerable.SequenceEqual(a1, a2); 实际上。

标签: c# image hash byte hashcode


【解决方案1】:

我知道比较字节数组的 3 种方法:

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

对于您的代码,您可以轻松尝试:

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

在初始化 Bitmap im2 后立即将其添加到您的代码中,并在输出窗口中查看结果。您可以使用其中任何一个来比较和评估数组是否相同。

注意System.Text.Encoding.UTF8.GetString不适合在这种情况下使用(来自图片的哈希数据)。请参阅下面@CodesInChaos 的评论。

【讨论】:

  • 第二个只在字节是 UTF-8 编码的文本时才有效,而哈希不是。理智的实现会在输入无效时引发异常,不幸的是,.net 中的默认实现会默默地破坏数据。例如Encoding.UTF8.GetString(new byte[]{0xFF}) == Encoding.UTF8.GetString(new byte[]{0x80}).
  • 好点,谢谢,我在回答中包含了对此的评论。
  • 转换为字符串绝不是比较字节数组的好方法。从不。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
  • 2022-11-07
  • 1970-01-01
  • 2019-03-26
相关资源
最近更新 更多