Comparison of bmp files?

橙三吉。 提交于 2019-12-06 04:01:05

I don't know on which platform you want to implement this, but here are some code snippets which could be useful:

Compare two images with C#

This is a snippet to compare 2 images to see if they are the same. This method first converts each Bitmap to a byte array, then gets the hash of each array. We then loop through each in the hash to see if they match.

/// <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)
{
  ...
}

Well, you have at least two options here:

  • The images are mostly the same
    In this case, I'd recommend a compare using splattne's solution

  • The images are usually different, and only sometimes the same
    In this case, it might be that you can dismiss any similarity between the two images with a quick comparison of the information header (think "is the size the same?), and only do the full comparison if the information is ambiguous (i.e. the size is the same)

You may want to use an extension method in .NET 3.0+ for this to expose the compare method on all the Bitmaps:

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

What are you comparing for? Are you looking to see if 2 images are exactly the same? Or do you need degrees of difference? For exact matches how about creating and comparing hashes of both files?

The above solutions didn't work for me when I had two images that only differed in color depth--one was 32bpp and the other was 8bpp. The solution I arrived at used LockBits to convert all images to 32bpp, Marshal.Copy() to get the data into an array and then just compare the arrays.

/// <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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!