私は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を通過したビットマップにアクセスしようとするとエラーが発生しました。以下の回避策がありますが、固定メモリのブロックが横になっているかどうかはわかりません。 (メモリリークアラート!)
質問を忘れて、私は言葉を理解していないのですか? – LukeHennerley
@LukeHennerley通常、 'LockBits'を使うつもりならば' unsafe'コードを続けてメモリに直接アクセスします。私は 'LockBits'を使っていて、' unsafe'コードを使っていません。 – AppFzx
これはかなり一般的ですが、GDI +は一般的に非常に厄介な例外レポートを持ち、復讐を遅らせる傾向があります。代わりにBitmap.Clone()を使用してください。 –