使用Image.FromHbitmap()构造位图时,多久可以删除原始位图句柄? [英] When constructing a Bitmap with Image.FromHbitmap(), how soon can the original bitmap handle be deleted?

查看:620
本文介绍了使用Image.FromHbitmap()构造位图时,多久可以删除原始位图句柄?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自Image.FromHbitmap()的文档,位于 http ://msdn.microsoft.com/zh-CN/library/k061we7x%28VS.80%29.aspx :

FromHbitmap方法复制GDI位图.因此您可以在创建新图像后立即使用GDIDeleteObject方法释放传入的GDI位图.

The FromHbitmap method makes a copy of the GDI bitmap; so you can release the incoming GDI bitmap using the GDIDeleteObject method immediately after creating the new Image.

这很明确地指出,一旦创建了位图实例,就可以立即使用DeleteObject删除位图句柄.

This pretty explicitly states that the bitmap handle can be immediately deleted with DeleteObject as soon as the Bitmap instance is created.

但是,通过Reflector看Image.FromHbitmap()的实现,表明它是GDI +函​​数GdipCreateBitmapFromHBITMAP()的一个非常薄的包装.

Looking at the implementation of Image.FromHbitmap() with Reflector, however, shows that it is a pretty thin wrapper around the GDI+ function, GdipCreateBitmapFromHBITMAP().

关于GDI +平面API函数的文档很少,但是

There is pretty scant documentation on the GDI+ flat API functions, but http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx says that GdipCreateBitmapFromHBITMAP() corresponds to the Bitmap::Bitmap() constructor that takes an HBITMAP and an HPALETTE as parameters.

Bitmap::Bitmap()构造函数版本的文档,位于

The documentation for this version of the Bitmap::Bitmap() constructor at http://msdn.microsoft.com/en-us/library/ms536314%28VS.85%29.aspx has this to say:

您负责删除GDI位图和GDI调色板.但是,在删除GDI + Bitmap :: Bitmap对象或超出范围之后,才应该删除GDI位图或GDI调色板.

You are responsible for deleting the GDI bitmap and the GDI palette. However, you should not delete the GDI bitmap or the GDI palette until after the GDI+ Bitmap::Bitmap object is deleted or goes out of scope.

请勿将当前(或以前)选择进入设备上下文的GDI位图或GDI调色板传递给GDI + Bitmap :: Bitmap构造函数.

Do not pass to the GDI+ Bitmap::Bitmap constructor a GDI bitmap or a GDI palette that is currently (or was previously) selected into a device context.

此外,可以在GdiPlusBitmap.h中的GDI +的C ++部分的源代码中看到,所讨论的Bitmap::Bitmap()构造函数本身就是平面API中GdipCreateBitmapFromHBITMAP()函数的包装器:

Furthermore, one can see in the source code for the C++ portion of GDI+ in GdiPlusBitmap.h that the Bitmap::Bitmap() constructor in question is itself a wrapper for the GdipCreateBitmapFromHBITMAP() function from the flat API:

inline 
Bitmap::Bitmap(
    IN HBITMAP hbm, 
    IN HPALETTE hpal
    )
{
    GpBitmap *bitmap = NULL;

    lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);

    SetNativeImage(bitmap);
}

我不容易看到GdipCreateBitmapFromHBITMAP()的实现,这是此功能的核心,但是文档中的两个注释似乎是矛盾的. .Net文档说我可以立即删除位图句柄,而GDI +文档说必须保留位图句柄,直到删除包装对象为止,但是两者都基于相同的GDI +函​​数.

What I can't easily see is the implementation of GdipCreateBitmapFromHBITMAP() that is the core of this functionality, but the two remarks in the documentation seem to be contradictory. The .Net documentation says I can delete the bitmap handle immediately, and the GDI+ documentation says the bitmap handle must be kept until the wrapping object is deleted, but both are based on the same GDI+ function.

此外,GDI +文档警告不要使用当前或先前在设备上下文中选择的源HBITMAP.虽然我可以理解为什么当前不应该将位图选择到设备上下文中,但是我不理解为什么会有警告,提示不要使用先前在设备上下文中选择的位图.这似乎会阻止使用在内存中使用标准GDI创建的GDI +位图.

Furthermore, the GDI+ documentation warns against using a source HBITMAP that is currently or previously selected into a device context. While I can understand why the bitmap should not be selected into a device context currently, I do not understand why there is a warning against using a bitmap that was previously selected into a device context. That would seem to prevent use of GDI+ bitmaps that had been created in memory using standard GDI.

因此,总而言之:

  1. 是否需要保留原始位图句柄,直到处置.Net位图对象?
  2. GDI +函​​数GdipCreateBitmapFromHBITMAP()是复制源位图还是仅保留原始位图的句柄?
  3. 为什么我不应该使用先前在设备上下文中选择的HBITMAP?
  1. Does the original bitmap handle need to be kept around until the .Net Bitmap object is disposed?
  2. Does the GDI+ function, GdipCreateBitmapFromHBITMAP(), make a copy of the source bitmap or merely hold onto the handle to the original?
  3. Why should I not use an HBITMAP that was previously selected into a device context?

推荐答案

凭经验,.Net文档似乎是正确的.确实可以立即在传递给Image.FromHbitmap()的HBITMAP上调用DeleteObject(),这样做似乎没有不良影响.

Empirically, it seems the .Net documentation is correct. One can indeed immediately call DeleteObject() on the HBITMAP passed to Image.FromHbitmap() and there appear to be no ill effects from having done so.

根据我通过反向工程学到的代码,尽管这与已发布的文档相矛盾,但同样适用于GDI + Bitmap::Bitmap()构造函数和GDI + GdipCreateBitmapFromHBITMAP()函数.

Based on what I have learned by reverse engineering the code, the same would apply to the GDI+ Bitmap::Bitmap() constructor and the GDI+ GdipCreateBitmapFromHBITMAP() function as well, although this contradicts the published documentation.

也许GDI +文档过于保守-保留在未来版本中保留提供的HBITMAP句柄的权利.如果GDI +中发生了这种更改,则.Net框架必须进行更改以保留位图的副本,方法是在将位图传递给GDI +之前对其进行复制.

Perhaps the GDI+ documentation is being overly conservative - reserving the right to, in a future version, hold on to the provided HBITMAP handle. Should that change ever occur in GDI+, the .Net framework would have to change to preserve their published contract by making a copy of the bitmap before passing it to GDI+.

这篇关于使用Image.FromHbitmap()构造位图时,多久可以删除原始位图句柄?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆