除了使用 P/Invoke 之外,如何在 hBitmap 上调用 DeleteObject()?

问题描述 投票:0回答:2

我正在处理类似这样的代码(来自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
吗?

c# .net bitmap pinvoke hbitmap
2个回答
5
投票

我认为除了使用 p/invoke 之外,没有任何方法可以从 C# 调用

DeleteObject

因此,如果您想避免这种意外的非托管代码访问,那么您应该首先避免调用

GetHbitmap
。你可以很容易地做到这一点。你想做一个
BitmapSource
。拨打
BitmapSource.Create
即可完成此操作。


0
投票

这就是你的目的......

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必须手动处理掉;否则,每个调用都会继续消耗内存,直到没有剩余内存为止。向原始内容创建者致歉,我找不到当时派生此内容的页面的链接。

干杯

© www.soinside.com 2019 - 2024. All rights reserved.