关于提高AlphaBlend效率的思考

在做UI开发的时候,如果要实现比较漂亮的界面是需要大量用到透明渐变效果及不规则图片的,在前一篇中<关于TransparentBlt和AlphaBlend的不同>中曾经总结过要想显示当图像象素具有不同透明度或不规则图形边缘有渐变色需要平滑显示时要用alpha运算,特别是象素级alpha运算才能达到理想效果。

常规的alpha运算一般是调用系统的AlphaBlend(在下面所提到相同的函数名均是指系统函数)对图像资源进行混合运算,而常用的图像资源中一般是用到PNG和BMP。前者因为是进行了编码并能够携带Alpha通道信息,因此它的优点是:占用的空间要比BMP小,而且因为携带A通道信息就可以在做图的时候随心所欲的制做各种特效,在设备上解码后就可以用AlphaBlend显示了,缺点是因为需要解码所以设备要有相应组件(如Imaging)或其它解码器(如CxImage),而且如果设备配置不高的话解码速度也会打折扣;后者是无压缩的所以占用空间要比PNG大,但是却可以省掉解码这一步直接用GDI的DDB或DIB就可以操作了,缺点是32位以下的位图是不带A通道信息的,这样在做图的时候就不如PNG那样随意,而且在显示不规则的图形时因为只能指定单一透明色在边缘就会有锯齿影响显示效果。

有一个好的消息就是BPP32的BMP是可以携带A通道的,但是也有两个不太方便的地方就是:1、在PC下能够设计这种BMP的工具软件就算闻名如Photoshop都不是很方便,在实际开发中往往是先用IconWorksho这个软件将photoshop设计的PNG转换成32BPP的BMP;2、在用AlphaBlend对32BPP的BMP进行运算得出的并不是想象中的结果,这是因为需要将BMP预处理为PARGB格式,关于PARGB格式及转换公式可以在网上或MSDN对AlphaBlend参数BLENDFUNCTION说明中找到。

前面所提到的方法基本上就可以能够设计出漂亮的图片并且按预想的结果显示出来了,但是有一个很现实的问题就会出现了:漂亮的界面不是一副或两副就行了的,它是各种漂亮元素及特效组合起来的,为此会存在大量的alpha运算,在这种情况下AlphaBlend就有点力不从心了。如何提高alpha运算的效率呢?我想有几种方法可供选择:

1、用DIB管理BMP资源,然后直接用内存操作来实现象素的混合运算。经过一个大概的测试发现要比系统的函数要快很多,这个原因可能一个是AlphaBlend检测条件比较多,二来可能调用的是GDI的SetPixel,而SetPixel因为还执行了一些额外的操作效率是比较低的,不象DIB直接操作内存。不过AlphaBlend缩放算法做得很不错,自实现alpha运算需要缩放并能不能也达到所需效果是一个值得考虑的问题。

2、改进自实现混合算法,降低象素运算总的循环次数,自然速度就提高了。

3、将改进后的混合算法用汇编来实现,这个需要对平台指令有相当了解才能进行。
而下面的方法对平台架构的依赖性较大,需要根据具体情况决定。

4、ARMv6架构的SIMD指令实现:关于SIMD可以网上查找。比如MMX指令一次能对4个象素点进行混合运算,理论上而言速度能提高四倍。

5、LCD控制器具有Overlay、Aalpha、Colorkey功能:不过就掌握的情况来看只能进行常量的混合运算。

最后补充一点:关于是用PNG还是BMP,这要看设备的实际运行情况:可能有是瓶颈是在解码,而有的是在文件IO操作。。。,不过把alpha运算这个最大的瓶颈解决了这都好办了,而且如果借鉴很多游戏的做法把资源打包,在需要的时候加载不需要的时候卸载,对于象BMP这种压缩率能超过50%的文件将它加载到内存再解压应该还是要比单纯加载未压缩的要快吧。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值