.NET – When using image.fromhbitmap () to construct Bitmap, how long will the original bitmill handle will be deleted?

Image.FromHbitmap() document from http://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspx:

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.

< /blockquote>

This makes it very clear that once a Bitmap instance is created, you can use DeleteObject to immediately delete the bitmap handle.

However, looking at the implementation of Image.FromHbitmap() with Reflector, Shows that it is a very thin wrapper around the GDI function GdipCreateBitmapFromHBITMAP().

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

This version of the Bitmap::Bitmap() constructor The document at http://msdn.microsoft.com/en-us/library/ms536314%28VS.85%29.aspx says this:

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.

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.

In addition, you can see the C part of GDI in GdiPlusBitmap.h in the source code. 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);
)

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

In addition, the GDI documentation warns against using the source HBITMAP currently or previously selected into the device context. Although I can understand why bitmaps should not be selected into the device context at the moment, but I don’t understand why there is a warning about using the bitmap previously selected into the device context. This seems to prevent the GDI bits created in memory using standard GDI Figure.

So, to summarize:

>Before processing the .Net Bitmap object, do I need to retain the original bitmap handle?
> Does the GDI function GdipCreateBitmapFromHBITMAP() copy the source bitmap or just keep the original handle?
>Why can’t I use the HBITMAP previously selected in the device context?

Based on experience, it seems that the .Net document is correct. It can indeed be called immediately and passed to Image.FromHbitmap The DeleteObject() on the HBITMAP of () does not seem to have any adverse effects.

Based on the knowledge I learned through reverse engineering, the same applies to GDI Bitmap :: Bitmap() The constructor and the GDI GdipCreateBitmapFromHBITMAP() function, although this contradicts the published documentation.

Maybe the GDI documentation is too conservative-reserve the right to retain the provided HBITMAP handle in future versions. If in GDI With this change, the .Net framework must be changed by making a copy of the bitmap before passing it to GDI to retain its published contract.

Image.FromHbitmap() document of ://msdn.microsoft.com/en-us/library/k061we7x%28VS.80%29.aspx:

< p>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.

This is very clear, once Once a Bitmap instance is created, you can use DeleteObject to immediately delete the bitmap handle.

However, looking at the implementation of Image.FromHbitmap() with Reflector, it shows that it is a very thin one around the GDI function GdipCreateBitmapFromHBITMAP() Wrapper.

There is very little documentation about GDI flat API functions, but http://msdn.microsoft.com/en-us/library/ms533971%28VS.85%29.aspx says GdipCreateBitmapFromHBITMAP() Corresponds to HBITMAP and HPALETTE as Parameters of the Bitmap::Bitmap() constructor.

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

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.

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.

In addition, the C part of GDI in GdiPlusBitmap.h can be seen in the source code, the Bitmap::Bitmap() constructor in question It 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);
< br /> SetNativeImage(bitmap);
}

What I can’t easily see is the implementation of GdipCreateBitmapFromHBITMAP() , This is the core of the feature, but the two comments in the documentation seem to be contradictory. The .Net documentation says that I can delete the bitmap handle immediately, and the GDI documentation says that the bitmap handle must be kept until the packaging object is deleted, but both All are based on the same GDI function.

In addition, the GDI documentation warns against using the source HBITMAP currently or previously selected into the device context. Although I can understand why bitmaps should not be selected into the device context currently, But I don’t understand why there is a warning about using the bitmap previously selected to the device context. This seems to prevent the use of standard GDI to create GDI bitmaps in memory.

So, to summarize:

p>

>Is it necessary to keep the original bitmap handle before processing the .Net Bitmap object?
> Does the GDI function GdipCreateBitmapFromHBITMAP() copy the source bitmap or just keep the original handle?
>Why can’t I use the HBITMAP previously selected in the device context?

According to experience, it seems that the .Net documentation is correct. It is indeed possible to immediately call DeleteObject() on the HBITMAP passed to Image.FromHbitmap() to do so There does not seem to be any adverse effects.

Based on the knowledge I have learned through reverse engineering, the same applies to the GDI Bitmap::Bitmap() constructor and the GDI GdipCreateBitmapFromHBITMAP() function, although this is not the same as The published document is contradictory.

Maybe the GDI document is too conservative-reserve the right to retain the provided HBITMAP handle in future versions. If this change occurs in GDI, the .Net framework must be approved Before passing the bitmap to GDI, make a copy of the bitmap to change it to retain its published contract.

Leave a Comment

Your email address will not be published.