2 つの bmp ファイルを比較したい。私は2つのアプローチを考えました:
- 2 つのファイルのヘッダーと情報ヘッダーを比較する
- bmp ファイルをバイナリに変換してから、上記の比較を行います
しかし、どのように開始すればよいのか、どちらがより良いアプローチになるのかわかりません。誰かが私を助けてくれたらうれしいです!
2 つの bmp ファイルを比較したい。私は2つのアプローチを考えました:
しかし、どのように開始すればよいのか、どちらがより良いアプローチになるのかわかりません。誰かが私を助けてくれたらうれしいです!
これをどのプラットフォームに実装するかはわかりませんが、役立つコードの一部を次に示します。
これは、2 つの画像を比較して同じかどうかを確認するためのスニペットです。このメソッドは、最初に各 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)
{
...
}
.NET 3.0以降の拡張メソッドを使用して、すべてのビットマップで比較メソッドを公開することをお勧めします。
public static bool Compare(this Bitmap bmp1, Bitmap bmp2)
{
//put your comparison logic here
}
ここには、少なくとも2つのオプションがあります。
画像はほとんど同じ
ですこの場合、splattneのソリューションを使用して比較することをお勧めします
画像は通常異なり、場合によっては同じ
です。この場合、情報ヘッダーをすばやく比較して(「サイズは同じですか?」と考えてください)、2つの画像間の類似性を無視して、情報があいまいな場合(つまり、サイズが同じ場合)の完全な比較
上記の解決策は、色深度のみが異なる2つの画像がある場合は機能しませんでした。1つは32bppで、もう1つは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;
}
何を比較しているのですか?2 つの画像がまったく同じかどうかを確認しますか? それとも差の程度が必要ですか?完全に一致するには、両方のファイルのハッシュを作成して比較するのはどうですか?