关于TransparentBlt和AlphaBlend的不同

一、关于TransparentBlt和AlphaBlend的不同
这两个函数在实际使用中是有不同的,关于此可以参见http://blog.csdn.net/jmunic/archive/2009/10/26/4728420.aspx,如果用一句话总结那就是:前者是图形带透明色的部分底图才能显示,后者是不管有没有透明色都根据透明程度显示底图。
在实际使用中有这样一个技巧:对于规则图形如果要半透明底图可以直接用AlphaBlend指定一个alpha常值,图形本身可以不带alpha信息,因为整副图都要显示不存在透明色此时用TransparentBlt没有意义。而对于不规则图形(如圆形按钮)图形外部是不需要显示出来的,它的边缘为了显示的时候不出现锯齿往往是有渐变色的,此时如果指定一个透明色并调用TransparentBlt在边缘就会出现锯齿,而且底图也会被盖住无法半透明。因此就需要图形本身带alpha信息,然后每个象素和要贴图位置的底图对应象素都进行AlphaBlend,这样才能达到既能平滑显示边缘又能半透明底图。

二、AlphaBlend和透明位图的深入思考
1、32位的位图可以带alpha通道,但是不知为何用photoshop无法生成这样的图。将带alpha的png可以通过IconWorkshop转换成带alpha通道的32位位图(见参考一)。有一点要说明的是对于PNG,alpha为0的地方在电脑上是不会显示的,而对于BMP,alpha为0的地方是会显示为黑色的。
2、AlphaBlend如果指定AlphaFormat为AC_SRC_ALPHA,SourceConstantAlpha为255则可以利用图像自带的alpha通道信息来绘图,这种方法当图像象素具有不同透明度的情况下很有用,特别是象那种不规则图形边缘有渐变色需要平滑显示时;否则是用统一的alpha值进行运算,这种方法在图像无或不关心alpha通道的时候比较常用。
3、通过IImage接口可以把PNG转成ARGB保存到HBITMAP,在需要的时候按照(2)的方法贴图(见参考二),或者用IImage的Draw方法直接贴图(见参考三),但是因为每次都要解码(瓶颈)会影响速度。
4、在实际使用中发现方法(3)对32位带alpha通道的位图无法显示,但是在用SHLoadDIBitmap加载这种位图再用(2)的方法(见参考四)却可以,具体原因还不清楚,另外也可以通过临时DC进行两次AlphaBlend的的方法(可见参考五)。
5、有些边缘带特效的PNG转换成32位的位图时,因为特效区域的alpha是255(不透明)会变成白色,如果用方法(4)也会把这个白色显示出来,只能用方法(3),具体原因还不清楚。是否需要先将R、G、B和A分离出来进行运算?
6、上述的方法是需要系统有相应组件支持才行的,如果没有则要自实现。在参考MSDN中关于BLENDFUNCTION的说明中相关算法的前提下应该是可以实现的(见参考六)。

三、引用
参考一:http://bbs.crsky.com/read.php?tid=877300
参考二:http://www.winbile.net/bbs/blogs/ice520301/archive/2009/12/25/155.aspx
参考三:http://www.armce.com/bbs/thread-782-1-1.html
参考四:http://www.56jiemeng.com/a/mengjianguishen/2010/0413/74234.html
参考五:http://bottlerun.spaces.live.com/blog/cns!40009282A442F870!188.entry
参考六:http://blog.chinaunix.net/u2/61062/showart_2055492.html

***************************************************

新发现:如果指定目标高宽和源不同,则会有缩放功能,而且效果还不错

你可能感兴趣的:(算法,图形,2010)