I'm a little confused about how .NET manages images, I have the following code to create a managed raster form of an unmanaged HBitmap, while preserving the alpha channel.
public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap) { Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap); if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32) return bmp; BitmapData bmpData; if (IsAlphaBitmap(bmp, out bmpData)) { // MY QUESTION IS RELATED TO THIS // IF CALL SUPPRESS_FINALIZE THE OBJECT // IT WILL WORK, OTHERWISE IT FAILS GC.SuppressFinalize(bmp); return new Bitmap( bmpData.Width, bmpData.Height, bmpData.Stride, PixelFormat.Format32bppArgb, bmpData.Scan0); } return bmp; } private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData) { Rectangle bmpBounds = new Rectangle(0, 0, bmp.Width, bmp.Height); bmpData = bmp.LockBits(bmpBounds, ImageLockMode.ReadOnly, bmp.PixelFormat); try { return IsAlphaBitmap(bmpData); } finally { bmp.UnlockBits(bmpData); } } private static bool IsAlphaBitmap(BitmapData bmpData) { for (int y = 0; y <= bmpData.Height - 1; y++) { for (int x = 0; x <= bmpData.Width - 1; x++) { Color pixelColor = Color.FromArgb( Marshal.ReadInt32(bmpData.Scan0, (bmpData.Stride * y) + (4 * x))); if (pixelColor.A > 0 & pixelColor.A < 255) { return true; } } } return false; }
Ok, I know that the line is GC.SuppressFinalize(bmp); it makes no sense, but when I delete this line, sometimes (every 4 or 5 calls), I get the following exception:
Attempted to read or write protected memory. It is often that other memory is corrupted.
I suspect that garbage collects the bmp object before the inverse bitmap is drawn, so it will try to access the bits that are located in the structure. If I never collect bmp, it works, but it causes a memory leak (the bmp link is never collected).
Do you know how I can solve this problem?
source share