2016-08-16 5 views
0

2つの画像の間の100x100ピクセルの小さなブロックを比較しようとします。 私は、これは私のコードで、LockBits操作後にネイティブmemcmpのPInvoke呼び出しを使用します。c#ビットマップブロックの比較

private void CompareBlock(Bitmap bmp1,Bitmap bmp2) 
    { 
     Rectangle lockRect = new Rectangle(0, 0, bmp1.Width, bmp1.Height); 
     BitmapData bmData = bmp1.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 
     BitmapData bmData2 = bmp2.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 
     IntPtr scan0 = bmData.Scan0; 
     IntPtr scan02 = bmData2.Scan0; 
     int BytesPerPixel = 4;//images are 32bpprgb 
     Size BlockSize = new Size(100,100); 
     if (memcmp(scan0, scan02, (BlockSize.Width * BlockSize.Height * BytesPerPixel))==0)//need to compare only the the first 100x100 pixels block. 
     { 
      Console.WriteLine("Equal"); 
      //do somthing with the block; 
     } 
    } 

である私は私が間違ってやっているかわからないんだけど、プログラムが実際に条件を入力し、印刷し"Equal"真実ではない(与えられたイメージによると)。

私は助けていただきありがとうございます。

ありがとうございました。

//コード更新されたテスト

 private void CompareBlock(Bitmap bmp1,Bitmap bmp2) 
    { 
     Rectangle lockRect = new Rectangle(0, 0, bmp1.Width, bmp1.Height); 
     BitmapData bmData = bmp1.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 
     BitmapData bmData2 = bmp2.LockBits(lockRect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb); 
     IntPtr scan0 = bmData.Scan0; 
     IntPtr scan02 = bmData2.Scan0; 
     int BytesPerPixel = 4; 
     Size BlockSize = new Size(100,100); 

     for (int y = 0; y < BlockSize.Height; y++) 
     { 
      if (memcmp(scan0, scan02, BlockSize.Width * BytesPerPixel) == 0)//need to compare only the the first 100x100 pixels block. 
      { 
       scan0 = IntPtr.Add(scan0, stride);//not sure about that advancement 
       scan02 = IntPtr.Add(scan02, stride2);//not sure about that advancement 

       //do somthing with the block; 
      } 
      else 
       break; 
     } 
    } 

enter image description here enter image description here

+0

数日前に[このプロジェクト](http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp)をビットマップをロックする必要があった人にお勧めしました。あなたの問題を解決するのに役立つかもしれません。 –

答えて

0

私はあなたのコードは、あなたがそれだと思う何をやっているとは思いません。

BitmapDataのScan0値は、ビットマップ内の最初のピクセルのアドレスを示します。次に、100 x 100 x 32のXバイト(BlockSize.Width * BlockSize.Height * BytesPerPixel)のメモリスペースをトラバースします。

これは100x100ブロックではなく、最初の数行のスキャンラインになります。 BitmapData.Strideプロパティを使用して算術演算を行い、スキャンラインに含まれるピクセル数を計算する必要があります。各スキャンラインの最初の100xBytesPerPixelバイトだけを必要とし、次のスキャンラインの開始までメモリポインタをスキップするように進みます。

+0

私はコードを更新しました。それはあなたが意味するものですか?私はブロックを比較するために各行を繰り返す必要がありますか? : 現在のコードが正常に動作しているかどうかわかりません。どうぞご覧ください。 – Slashy

+0

これは正しい方法です。各行を繰り返し処理する必要があります。 2D配列ではなく、一連のスキャンライン(Bit DepthにBitmap Widthを掛けた長さよりも長くなる可能性があるので、Strideを使用する理由です)を使用すると、ビットマップの1行の正確なメモリフットプリントが得られます。 – PhillipH

+0

i 'ここで長い仕事をしなければなりません...私の画面の各ブロックを比較する必要があります。**画面全体** :( – Slashy