以下の項目が同じなら同じBitmapSource
要は色が同じかどうかの、見た目重視で判定したい
テストアプリ
using System;
using System.Windows;
using System.Windows.Media.Imaging;
<summary>
</summary>
namespace _20191003_MD5ハッシュ値で画像比較
{
<summary>
</summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
string fileName;
fileName = @"D:\ブログ用\チェック用2\WP_20190714_22_18_03_Pro_2019_07_14_午後わてん.jpg";
Uri uri = new Uri(fileName);
BitmapSource bmp10 = new BitmapImage(uri);
BitmapSource bmp11 = new BitmapImage(uri);
bool neko = bmp10 == bmp11;
bool inu = bmp10.Equals(bmp11);
bool uma = IsBitmapEqual(bmp10, bmp11);
fileName = @"D:\ブログ用\チェック用2\WP_20190714_22_18_03_Pro_2019_07_14_午後わてん - コピー.jpg";
BitmapSource bmp20 = new BitmapImage(new Uri(fileName));
bool tori = IsBitmapEqual(bmp10, bmp20);
fileName = @"D:\ブログ用\テスト用画像\8x8_100と2002色.png";
BitmapSource bmp30 = new BitmapImage(new Uri(fileName));
bool saru = IsBitmapEqual(bmp10, bmp30);
}
<summary>
</summary>
<param name="bmp1"></param>
<param name="bmp2"></param>
<returns></returns>
private bool IsBitmapEqual(BitmapSource bmp1, BitmapSource bmp2)
{
if (bmp1 == null || bmp2 == null) return false;
var md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] h1 = md5.ComputeHash(MakeBitmapByte(bmp1));
byte[] h2 = md5.ComputeHash(MakeBitmapByte(bmp2));
md5.Clear();
return IsArrayEquals(h1, h2);
}
private bool IsArrayEquals(byte[] h1, byte[] h2)
{
for (int i = 0; i < h1.Length; i++)
{
if (h1[i] != h2[i])
{
return false;
}
}
return true;
}
private byte[] MakeBitmapByte(BitmapSource bitmap)
{
int w = bitmap.PixelWidth;
int h = bitmap.PixelHeight;
int stride = w * bitmap.Format.BitsPerPixel / 8;
byte[] pixels = new byte[h * stride];
bitmap.CopyPixels(new Int32Rect(0, 0, w, h), pixels, stride, 0);
return pixels;
}
}
}
github.com
30行目のbmp10と、31行目のbmp11は同じ画像ファイルから作成したBitmapSourceなので、サイズや色は完全に同じ、1ピクセルも違いがないので、この2つは同じだと判定したい
けど、単純に==で比較した33行目と、BitmapSourceクラスのEqualsで比較した34行目はどちらも
false、違うものと判定される
これは参照とかメモリのどこに入っているかの比較になっているんだろうねえ
そうじゃなくてもっとこう、見た目的な意味で同じかどうかを知りたい
ググって
blog.kur.jp
ピクセルの色をbyte配列にして、それのMD5のハッシュ値を比較すればいいと
ハッシュ値の求め方は
dobon.net
System.Security.Cryptography.MD5CryptoServiceProviderの
ComputeHash関数でbyte型配列になったハッシュ値が得られる
これらをもとに書いたのが55行目以降の
IsBitmapEqual
これに比較したい2つのBitmapSourceを渡すと、同じならtrue、違ったらfalseが返ってくる
bmp10とbmp11を渡した結果は
true、期待通り!
bmp10の元になった画像ファイルをコピーして、別名で保存したものから作成したBitmapSourceのbmp20との比較
別ファイルだけど画像のサイズや色は同じだからtrueになるはず
いいねえ
次は全く違う画像から作成したbmp30との比較、結果はfalseのはず
期待通り
MD5以外
強そうなのが用意されているねえ
関連記事
gogowaten.hatenablog.com
2019/10/04は翌日