如何使用Win32 AlphaBlend函数绘制32bppargb图像?

时间:2010-01-15 11:50:17

标签: c# graphics winapi gdi+ gdi

我一直在为这个晚上的大部分时间而烦恼,所以也许你们其中一个人可以帮我一臂之力。

我发现C#中的GDI + DrawImage对于我想要呈现的内容来说太慢了,从论坛的外观来看,对其他人来说也是如此。

我决定尝试使用Win32 API中的AlphaBlendBitBlt来获得更好的性能。无论如何,我已经让我的图像显示得很好,除了一个小细节 - 无论我使用什么图像格式,我都无法让白色背景从我的(透明)图形中消失。

到目前为止,我已尝试过BMP和PNG格式,并验证它们是以C#中的32bppargb图像加载的。

这是我正在制作的电话:

// Draw the tile to the screen.
Win32GraphicsInterop.AlphaBlend(graphicsCanvas, destination.X, destination.Y, this.TileSize, this.TileSize,
                                this.imageGraphicsPointer, tile.UpperLeftCorner.X, tile.UpperLeftCorner.Y,
                                this.TileSize, this.TileSize,
                                new Win32GraphicsInterop.BLENDFUNCTION(Win32GraphicsInterop.AC_SRC_OVER, 0,
                                                                                   Convert.ToByte(opacity * 255),
                                                                                   Win32GraphicsInterop.AC_SRC_ALPHA));

对于记录,AC_SRC_OVER0x00AC_SRC_ALPHA0x01,这与MSDN所说的应该是一致的。

你们中的任何人都能很好地解决这个问题,或者知道一种更好(但仍然很快)的方法吗?

3 个答案:

答案 0 :(得分:5)

Graphics.DrawImage()速度严重依赖于像素格式。 Format32bppPArgb比我尝试过的任何一台机器上的任何其他机器快10倍。

另外请确保图像没有调整大小,请务必使用DrawImage()重载,将目标大小设置为等于位图大小。如果视频适配器的DPI设置与位图的分辨率不匹配,则非常重要。

答案 1 :(得分:1)

您是否尝试过仅为255而不是计算出的不透明度?

此博客文章描述了您要做的事情: - http://blogs.msdn.com/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx

关键是他执行图像转换以使alpha通道兼容..

答案 2 :(得分:1)

确定。从纯Win32的角度来看:

为了使AlphaBlend实际上是alpha混合......它需要源设备上下文包含一个选定的HBITMAP,表示具有32bpp位图和预乘Alpha通道的图像。 要获得具有32bpp的设备位图,您可以调用将创建屏幕兼容设备位图的众多功能之一,并希望用户选择32bpp作为桌面bitdepth。或者,确保源位图是DIBSection。好吧,从你为加载的图像创建它的库或框架。

所以,C#正在用32bpp argb加载你的图像,但是,你如何将位图的C#表示转换为HBITMAP?您需要确保正在创建DIB部分,而不是DDB(或设备相关的位图),并且DIB部分是32bpp。