C# 为什么GC使下面的代码段失败
我对.NET如何管理图像有点困惑,我有以下代码,从非托管HBitmap构建一个托管位图,保留alpha通道C# 为什么GC使下面的代码段失败,c#,.net,image,bitmap,unmanaged,C#,.net,Image,Bitmap,Unmanaged,我对.NET如何管理图像有点困惑,我有以下代码,从非托管HBitmap构建一个托管位图,保留alpha通道 public static Bitmap GetBitmapFromHBitmap(IntPtr nativeHBitmap) { Bitmap bmp = Bitmap.FromHbitmap(nativeHBitmap); if (Bitmap.GetPixelFormatSize(bmp.PixelFormat) < 32)
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;
}
公共静态位图GetBitmapFromHBitmap(IntPtr nativeHBitmap)
{
位图bmp=位图.FromHbitmap(nativeHBitmap);
if(位图.GetPixelFormatSize(bmp.PixelFormat)<32)
返回bmp;
位图数据bmpData;
if(isalHabitMap(bmp,out bmpData))
{
//我的问题与此有关
//如果调用SUPPRESS\u,则完成对象
//它会工作的,否则它会失败
气相色谱法(bmp);
返回新位图(
bmpData.Width,
bmpData.高度,
bmpData.Stride,
PixelFormat.Format32bppArgb,
bmpData.Scan0);
}
返回bmp;
}
专用静态布尔ISALPABITMAP(位图bmp,输出位图数据bmpData)
{
矩形bmpBounds=新矩形(0,0,bmp.Width,bmp.Height);
bmpData=bmp.LockBits(bmpBounds,ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{
返回isalHabitMap(bmpData);
}
最后
{
bmp.UnlockBits(bmpData);
}
}
专用静态bool IsAlphaBitmap(位图数据bmpData)
{
对于(int y=0;y请查看
调用者负责分配和释放scan0参数指定的内存块。但是,在释放相关位图之前,不应释放内存。
这意味着您需要确保保留bmpData
指向的底层内存块,直到释放GetBitmapFromHBitmap
返回的Bitmap
实例
导致您的问题的原因是垃圾收集器检测到bmp
无法访问(未使用)因此收集/终结它,这肯定会释放底层内存块,但是即使你抑制终结器,你仍然调用了UnlockBits
,这意味着bmpData
无论如何都是无效的-此时它可能会工作,但这完全是偶然的上述代码正确您需要找到一种机制,使bmpData
(并扩展为bmp
)在返回的Bitmap
实例存在的时间内保持有效,即可能对您的应用程序进行重大更改
或者,请查看一种完全不同的方法来实现(我认为)您想要实现的目标,同时完全避免所有这些问题。请看一看
调用者负责分配和释放scan0参数指定的内存块。但是,在释放相关位图之前,不应释放内存。
这意味着您需要确保保留bmpData
指向的底层内存块,直到释放GetBitmapFromHBitmap
返回的Bitmap
实例
导致您的问题的原因是垃圾收集器检测到bmp
无法访问(未使用)因此收集/终结它,这肯定会释放底层内存块,但是即使你抑制终结器,你仍然调用了UnlockBits
,这意味着bmpData
无论如何都是无效的-此时它可能会工作,但这完全是偶然的上述代码正确您需要找到一种机制,使bmpData
(并扩展为bmp
)在返回的Bitmap
实例存在的时间内保持有效,即可能对您的应用程序进行重大更改
或者,你可以用一种完全不同的方式去做(我认为)你想要实现的事情,同时完全避免所有这些问题