我一直在为这个晚上的大部分时间而烦恼,所以也许你们其中一个人可以帮我一臂之力。
我发现C#中的GDI + DrawImage
对于我想要呈现的内容来说太慢了,从论坛的外观来看,对其他人来说也是如此。
我决定尝试使用Win32 API中的AlphaBlend
或BitBlt
来获得更好的性能。无论如何,我已经让我的图像显示得很好,除了一个小细节 - 无论我使用什么图像格式,我都无法让白色背景从我的(透明)图形中消失。
到目前为止,我已尝试过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_OVER
为0x00
,AC_SRC_ALPHA
为0x01
,这与MSDN所说的应该是一致的。
你们中的任何人都能很好地解决这个问题,或者知道一种更好(但仍然很快)的方法吗?
答案 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。