我正在处理类似这样的代码(来自here)
using (var bmp = new System.Drawing.Bitmap(1000, 1000))
{
IntPtr hBitmap = bmp.GetHbitmap();
var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap, IntPtr.Zero, Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
}
MSDN 说,每当我调用
Bitmap.GetHbitmap()
时,我都必须在 DeleteObject()
上调用 hBitmap
来释放非托管资源。
我见过的所有答案和 MSDN 都说我必须 P/Invoke
DeleteObject()
函数。这看起来有点疯狂,因为我在没有 P/Invoke 的情况下获得了 hBitmap
,现在我突然需要使用 P/Invoke 来正确摆脱它。
除了 P/Invoke 真的没有其他办法让
DeleteObject()
呼叫我的 hBitmap
吗?
我认为除了使用 p/invoke 之外,没有任何方法可以从 C# 调用
DeleteObject
。
因此,如果您想避免这种意外的非托管代码访问,那么您应该首先避免调用
GetHbitmap
。你可以很容易地做到这一点。你想做一个BitmapSource
。拨打 BitmapSource.Create
即可完成此操作。
这就是你的目的......
using System;
using System.Drawing;
using System.Windows.Media;
using System.Runtime.InteropServices;
private BitmapSource Bmp2BmpSrc(Bitmap bitmap)
{
IntPtr hBitmap = bitmap.GetHbitmap();
BitmapSource bs;
try
{
bs = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
} finally { DeleteObject(hBitmap); }
return bs;
}
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
hBitmap必须手动处理掉;否则,每个调用都会继续消耗内存,直到没有剩余内存为止。向原始内容创建者致歉,我找不到当时派生此内容的页面的链接。
干杯