2013-02-07 1 views
6

私はC#でビットマップをコピーする方法がはるかに高速であると思っています。 (有効な場合、私は最初ではなかったと確信していますが、まだどこでも見ていません)。このようにlockbitsを使用してビットマップ領域をコピーするのは安全ですか(言い訳があります)?

私が考えることができる最も簡単な方法は、 UnlockBits

を使用して編集し、コピーバックする固定メモリへのビットマップのうちコピー画素データのブロックを単にLockBits

void FastCopyRegion(Bitmap CopyMe, ref Bitmap IntoMe, Rectangle CopyArea) 
    { 
     //`IntoMe` need not be declared `ref` but it brings 
     // attention to the fact it will be modified 
     Debug.Assert(CopyMe.PixelFormat == IntoMe.PixelFormat, 
      "PixelFormat mismatch, we could have a problem"); 
     Debug.Assert(CopyMe.Width == IntoMe.Width, //This check does not verify 
      "Stride mismatch, we could have a problem");// sign of `stride` match 
     BitmapData copyData = CopyMe.LockBits(CopyArea, 
      ImageLockMode.ReadWrite, CopyMe.PixelFormat); 
     IntoMe.UnlockBits(copyData); 
    } 

1:誰もそれに穴を撮影しない、考えが健全であると仮定します2)LockBitsを使用しても、コピーされたメモリブロックには影響しないので、コピー元の画像には影響しません。

3)unsafeコードを絶対入力しないので、メモリが破壊される危険はありません。私が見

可能な穴:

1)2つのビットマップのPixelFormat sが異なっている場合、このメソッドは常に正しく複製することはできません。ただし、LockBitsはピクセル形式を指定する必要があるため、これが処理されるようです。 (もしそうなら、そのオーバヘッドのために、我々はピクセルフォーマットを変更していない時間の99.9%/ EndSarcasm)

2)2つのビットマップのストライドが一致しないと、 strideは、コピー操作でのforループのインクリメンタの外側です)。この問題は、等しいストライドを持つビットマップへのコピーを制限します。

編集:私はアサーション2が間違っていなければならないと思います...後でCopyMeを通過したビットマップにアクセスしようとするとエラーが発生しました。以下の回避策がありますが、固定メモリのブロックが横になっているかどうかはわかりません。 (メモリリークアラート!)

+5

質問を忘れて、私は言葉を理解していないのですか? – LukeHennerley

+0

@LukeHennerley通常、 'LockBits'を使うつもりならば' unsafe'コードを続けてメモリに直接アクセスします。私は 'LockBits'を使っていて、' unsafe'コードを使っていません。 – AppFzx

+3

これはかなり一般的ですが、GDI +は一般的に非常に厄介な例外レポートを持ち、復讐を遅らせる傾向があります。代わりにBitmap.Clone()を使用してください。 –

答えて

3

代わりにBitmap.Clone()を使用してください。 GDI +は例外を報告しない傾向があり、結果として生じるバグは追跡が非常に難しくなります。

ビットマップにイメージをコピーするために非常に高速な方法は、限り、あなたはピクセルフォーマットを変換したり、画像をスケーリングしないようGraphics.DrawImage()です。

関連する問題