本文介绍了使用本地HBITMAP在C#中,而preserving alpha通道/透明度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我得到一个HBITMAP对象/从本机Windows函数处理。我可以用它转换为位图管理的 Bitmap.FromHbitmap(nativeHBitmap)的,但如果本机图像有透明度信息(alpha通道),它是由该转换丢失。

有关于这个问题的堆栈溢出几个问题。从这个问题的第一个答案使用信息(),我写了一篇code的,我试过和它的作品。

有基本上得到天然HBITMAP宽度,高度和使用指针到像素数据的位置的 GetObject的和 BITMAP 的结构,然后调用管理位图的构造

 位图managedBitmap =新位图(bitmapStruct.bmWidth,bitmapStruct.bmHeight,
    bitmapStruct.bmWidth * 4,PixelFormat.Format32bppArgb,bitmapStruct.bmBits);

据我了解(请纠正我,如果我错了),这不会从本机HBITMAP到托管位图拷贝的实际像素数据,它只是指向托管位来自本地HBITMAP像素数据。

和我不从这里得出的位图上的另一个图形(DC),或在其他位图,以避免不必要的内存复制,特别是对于大位图。

我可以将此位图简单地分配给PictureBox控件或窗体BackgroundImage属性。和它的作品,位图显示正确,使用的透明度。

当我不再使用位图,我要确保BackgroundImage属性不再指向位图,我都处理的管理位图和原生HBITMAP。

问题:你能告诉我,如果这个推理和code似乎是正确的。我希望我不会得到一些意外行为或错误。我希望我释放所有的内存和正确的对象。

 私人无效例()
    {
        IntPtr的nativeHBitmap = IntPtr.Zero;        / *此处获取从Windows功能本机HBITMAP对象* /        //创建BITMAP结构,并从我们的nativeHBitmap获取信息
        NativeMethods.BITMAP bitmapStruct =新NativeMethods.BITMAP();
        NativeMethods.GetObjectBitmap(nativeHBitmap,Marshal.SizeOf(bitmapStruct),REF bitmapStruct);        //创建使用指针天然HBITMAP的象素数据的管理的位图
        位图managedBitmap =新位图(
            bitmapStruct.bmWidth,bitmapStruct.bmHeight,bitmapStruct.bmWidth * 4,PixelFormat.Format32bppArgb,bitmapStruct.bmBits);        //显示位图
        this.BackgroundImage = managedBitmap;        / *运行程序,使用图像* /
        的MessageBox.show(正在运行...);        //当不再需要的图像,配置与被管位图对象和本机HBITMAP
        this.BackgroundImage = NULL;
        managedBitmap.Dispose();
        NativeMethods.DeleteObject(nativeHBitmap);
    }内部静态类NativeMethods
{
    [StructLayout(LayoutKind.Sequential)]
    公共结构位图
    {
        公众诠释bmType;
        公众诠释bmWidth;
        公众诠释bmHeight;
        公众诠释bmWidthBytes;
        公共USHORT bmPlanes;
        公共USHORT bmBitsPixel;
        公众的IntPtr bmBits;
    }    函数[DllImport(GDI32,字符集= CharSet.Auto,入口点=GetObject的)]
    公共静态外部INT GetObjectBitmap(IntPtr的hObject,诠释NCOUNT,楼盘BITMAP lpObject);    函数[DllImport(GDI32.DLL)]
    内部静态的extern BOOL DeleteObject的(IntPtr的hObject);
}


解决方案

右键,没有副本。这就是为什么在MSDN Library的备注部分说:

This wouldn't be a problem if the pixel data was copied. Incidentally, this is normally a difficult problem to deal with. You can't tell when the client code called Dispose(), there's no way to intercept that call. Which makes it impossible to make such a bitmap behave like a replacement for Bitmap. The client code has to be aware that additional work is needed.

这篇关于使用本地HBITMAP在C#中,而preserving alpha通道/透明度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-10 18:33