Is it safe (pun intended) to copy raster areas using locks this way?

I think I found a faster way to copy bitmaps in C #. (If this is true, I am sure that I am not the first, but I have not seen it anywhere else.)

The easiest way I can ask is to state what I based my idea on, and if no one shoots holes, suppose the idea sounds:

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) LockBits simply copies a block of pixel data from a raster image to a fixed memory that needs to be edited and copied using UnlockBits

2) Using LockBits does not affect the copied memory block, so it should not affect the image copied from.

3) Since you never enter unsafe code, there should be no risk of spoiling the memory.

Possible holes that I see:

1) If the PixelFormat two bitmaps is different, this method may not always be copied correctly. However, since LockBits requires pixelformat, it seems that this is being processed. (If so, cheers for this overhead in other 99.9% of cases where we don't switch pixelformats! / EndSarcasm)

2) If the step of the two bitmap images does not match, a problem may arise (since stride is the outer increment of the loop in the copy operation.) This problem limits copying to bitmap images with an equal step.

Edit: I think statement # 2 should be wrong ... I just discovered an error when I later tried to access a bitmap that went through CopyMe. The workaround is below, but I'm not sure if it leaves a fixed memory block around it. (memory leak warning!)

  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, "Width mismatch, we could have a problem"); BitmapData copyD = IntoMe.LockBits(CopyArea, ImageLockMode.ReadWrite, CopyMe.PixelFormat); BitmapData copyData = CopyMe.LockBits(CopyArea, ImageLockMode.ReadWrite, CopyMe.PixelFormat); CopyMe.UnlockBits(copyData); IntoMe.UnlockBits(copyData); } 
+6
source share
1 answer

Use Bitmap.Clone() instead. GDI + tends not to report exceptions, and errors received will be very difficult to track.

A very fast, fast way to copy images to a bitmap with Graphics.DrawImage() until you convert the pixel format or scale the image.

+3
source

All Articles