【问题标题】:How can you draw 32bppargb images with the Win32 AlphaBlend function?如何使用 Win32 AlphaBlend 函数绘制 32bppargb 图像?
【发布时间】:2011-01-05 11:39:03
【问题描述】:

我大半夜都在为此烦恼,所以也许你们中的一个可以帮我一把。

我发现 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 所说的应该是一致的。

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

【问题讨论】:

    标签: c# graphics winapi gdi+ gdi


    【解决方案1】:

    Graphics.DrawImage() 速度主要取决于像素格式。 Format32bppPArgb 在我最近尝试过的任何机器上都比其他任何机器快 10 倍。

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

    【讨论】:

    • 我不确定如何将我的图像转换为 Format32bppPArgb...它加载为 Format32bppArgb。有什么想法吗?
    • 使用让您指定 PixelFormat 的 Bitmap 构造函数。使用 Graphics.FromImage() 将原始位图绘制到其中。
    • 如何从Graphics 转换回Image
    【解决方案2】:

    您是否尝试过只设置 255 的不透明度而不是计算出来的不透明度?

    这篇博文描述了您正在尝试做的事情:- http://blogs.msdn.com/andreww/archive/2007/10/10/preserving-the-alpha-channel-when-converting-images.aspx

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

    【讨论】:

      【解决方案3】:

      好的。从纯 Win32 的角度来看:

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

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

      【讨论】:

        猜你喜欢
        • 2012-07-03
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 2018-09-01
        • 2014-05-26
        • 2014-05-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多