问题
I want to compare two bmp files. I thought of two approaches:
- to compare the header as well as the information header of the two files
- convert the bmp file to binary and then do the above comparison
But, I don't know how to start and which will be a better approach. I would be glad if someone could please help me!
回答1:
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)
{
...
}
回答2:
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 solutionThe 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)
回答3:
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
}
回答4:
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?
回答5:
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;
}
来源:https://stackoverflow.com/questions/649720/comparison-of-bmp-files