- 2010-03-03 (水) 0:16
- programming
一定時間毎にWebブラウザのウィンドウをキャプチャして,変更の有無を検出するコードを書いていたんだけど,ちょっと引っかかってしまったのでメモ.
最初,BitmapクラスにはGetHashCodeというメンバ関数があるから,ハッシュを取得してそれを比較すれば良いだろう,と簡単に考えていた.ところが,GetHashCodeというのはオブジェクトのハッシュを返す関数であり,画像データのハッシュを返すわけではない.つまり,この関数の返り値を比較しても,画像の内容が等しいか否かを判断することが出来ない.
じゃぁ,1pixelごと比較すれば良いのかと考えたのだけれども,BitmapクラスのGetPixelメソッドって,メチャクチャ遅い.そこで,Bitmapの中身をbyte配列に代入して,そのMD5をとることでハッシュ値を取得し,それを比較することで画像の変更の有無を検出することにした.
以下,具体的なコード.これだけの事なんだけど,思ったよりも時間を取ってしまった・・・.
Bitmap CurrentImg = GetScreenCaputureOf(Firefox);
BitmapData bmpdata = CurrentImg.LockBits(new Rectangle(0, 0, CurrentImg.Width, CurrentImg.Height), ImageLockMode.ReadWrite, CurrentImg.PixelFormat);
IntPtr ptr = bmpdata.Scan0;
int bytes = bmpdata.Stride * CurrentImg.Height;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
byte[] CurrentHash = new MD5CryptoServiceProvider().ComputeHash(rgbValues);
bool bEqual = false;
if (PrevHash!=null && PrevHash.Length == CurrentHash.Length)
{
int i = 0;
while ((i < PrevHash.Length) && (PrevHash[i] == CurrentHash[i]))
{
i += 1;
}
if (i == PrevHash.Length)
{
bEqual = true;
}
}
PrevHash = (byte[])CurrentHash.Clone();
if (!bEqual)
{
Console.WriteLine("Image Changed!");
}
参考にしたページ
- Newer: 企業の存在理由
- Older: 最近読んだ本とか書き出してみた2
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://kur.jp/2010/03/03/bitmap-compare/trackback/
- Listed below are links to weblogs that reference
- C#でBitmapの比較 from kur.jp