【问题标题】:Comparison of bmp files?bmp文件的比较?
【发布时间】:2009-03-16 09:15:23
【问题描述】:

我想比较两个 bmp 文件。我想到了两种方法:

  1. 比较两个文件的头和信息头
  2. 将bmp文件转成二进制再做上面的比较

但是,我不知道如何开始,哪种方法更好。如果有人可以帮助我,我会很高兴!

【问题讨论】:

  • 你在做什么类型的比较?你想检查它们是否是相同的副本?或者你想检查它们是否是相似的图像?第一个很简单,第二个有点棘手。
  • 我在 ANSI C 中有一个代码,可以在比较之前将两个文件标准化为 32bpp。我没有发布它,因为您似乎已经对 C# 代码感到满意

标签: file comparison diff bmp


【解决方案1】:

我不知道你想在哪个平台上实现这个,但这里有一些代码 sn-ps 可能有用:

Compare two images with C#

这是比较 2 张图片的 sn-p 看看它们是否相同。这 方法首先将每个 Bitmap 转换为 字节数组,然后获取每个的哈希 大批。然后我们循环遍历每一个 哈希以查看它们是否匹配。

/// <summary>
/// method for comparing 2 images to see if they are the same. First
/// we convert both images to a byte array, we then get their hash (their
/// hash should match if the images are the same), we then loop through
/// each item in the hash comparing with the 2nd Bitmap
/// </summary>
/// <param name="bmp1"></param>
/// <param name="bmp2"></param>
/// <returns></returns>
public bool doImagesMatch(ref Bitmap bmp1, ref Bitmap bmp2)
{
  ...
}

【讨论】:

    【解决方案2】:

    嗯,你至少有两个选择:

    • 图片大体相同
      在这种情况下,我建议使用 splattne 的解决方案进行比较

    • 图像通常不同,但有时相同
      在这种情况下,您可能可以通过快速比较信息标题来消除两个图像之间的任何相似性(想想“大小是否相同?),并且只有在信息不明确时才进行完整比较(即大小一样)

    【讨论】:

      【解决方案3】:

      您可能希望在 .NET 3.0+ 中使用扩展方法,以便在所有位图上公开比较方法:

          public static bool Compare(this Bitmap bmp1, Bitmap bmp2)
          {
              //put your comparison logic here
          }
      

      【讨论】:

        【解决方案4】:

        你在比较什么?您是否想查看两张图片是否完全相同?或者你需要不同的程度?对于精确匹配,如何创建和比较两个文件的哈希值?

        【讨论】:

          【解决方案5】:

          当我有两张颜色深度不同的图像时,上述解决方案对我不起作用——一张是 32bpp,另一张是 8bpp。我到达的解决方案使用 LockBits 将所有图像转换为 32bpp,Marshal.Copy() 将数据放入数组,然后只比较数组。

          /// <summary>
          /// Compares two images for pixel equality
          /// </summary>
          /// <param name="fname1">first image file</param>
          /// <param name="fname2">second image file</param>
          /// <returns>true if images are identical</returns>
          public static string PageCompare(string fname1, string fname2) {
              try {
                  using (Bitmap bmp1 = new Bitmap(fname1))
                  using (Bitmap bmp2 = new Bitmap(fname2)) {
                      if (bmp1.Height != bmp2.Height || bmp1.Width != bmp2.Width)
                          return false;
          
                      // Convert image to int32 array with each int being one pixel
                      int cnt = bmp1.Width * bmp1.Height * 4 / 4;
                      BitmapData bmData1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height),
                          ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                      BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height),
                          ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
          
                      Int32[] rgbValues1 = new Int32[cnt];
                      Int32[] rgbValues2 = new Int32[cnt];
          
                      // Copy the ARGB values into the array.
                      System.Runtime.InteropServices.Marshal.Copy(bmData1.Scan0, rgbValues1, 0, cnt);
                      System.Runtime.InteropServices.Marshal.Copy(bmData2.Scan0, rgbValues2, 0, cnt);
          
                      bmp1.UnlockBits(bmData1);
                      bmp2.UnlockBits(bmData2);
                      for (int i = 0; i < cnt; ++i) {
                          if (rgbValues1[i] != rgbValues2[i])
                              return false;
                      }
                  }
              }
              catch (Exception ex) {
                  return false;
              }
              // We made it this far so the images must match
              return true;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-01-15
            • 2017-05-09
            • 1970-01-01
            • 2014-11-16
            • 2021-02-16
            • 2021-11-17
            • 2017-06-10
            相关资源
            最近更新 更多