AlphaBlend函数的作用(msdn上的说明,不翻译了):The AlphaBlend function displays bitmaps that have transparent or semitransparent pixels
我使用AlphaBlend的目的是正常显示一个带透明效果的png图片,看了些文章,alpha混合的公式大概如下:
R(C)=alpha*R(B)+(1-alpha)*R(A)
G(C)=alpha*G(B)+(1-alpha)*G(A)
B(C)=alpha*B(B)+(1-alpha)*B(A)
自然通过该公式可以自己写代码实现alpha混合,但显然vb的效率没有调用win api的高,于是还是希望能采用AlphaBlend进行处理.
刚开始并没有仔细研究AlphaBlend的运作方式,只是尝试了几个png文件,发现显示正常,就算了,没有深究.后来遇到一些带alpha通道的BMP文件,发现用AlphaBlend无法正常显示,于是才仔细的看了AlphaBlend的说明.
AlphaBlend有个参数是BLENDFUNCTION类型的,此类型有个AlphaFormat ,如果设为AC_SRC_ALPHA ,那么AlphaBlend就会对源图象的每象素做alpha混合,msdn对此常量有如此解释
This flag is set when the bitmap has an Alpha channel (that is, per-pixel alpha). Note that the APIs use premultiplied alpha, which means that the red, green and blue channel values in the bitmap must be premultiplied with the alpha channel value. For example, if the alpha channel value is x, the red, green and blue channels must be multiplied by x and divided by 0xff prior to the call.
在此可以看出,处理时,首先会将每个分量(R,G,B)乘以对应的alpha值,这里可以看为是应了前面公式中的 alpha*R(B),接着在Remark中又提到,会做如下处理:
Dst.Red= Src.Red+ (1 - Src.Alpha) * Dst.Red
这里有个疑问,做这个处理的时候,前面提到的alpha*R(B)已经做了吗,假设是做了,那么为何显示不正确?尝试修改各参数,未果.难道是图象文件本来就有问题?于是尝试通过上述公式用代码来实现.于是发现显示正确,但是如果在R(C)=alpha*R(B)+(1-alpha)*R(A)中,如果去掉alpha*,也就是变成,R(C)=R(B)+(1-alpha)*R(A),显示出来的图象与用AlphaBlend处理的结果是一样的,那么这样子,几乎就可以肯定AlphaBlend采用的公式确实是:
Dst.Red= Src.Red+ (1 - Src.Alpha) * Dst.Red
但,为何对png图片又能正确显示呢?因为这里读取出来的png文件,alpha值较小的象素是黑色,这样最终合成的结果就不会有影响,而后来遇到的bmp文件,这些值很多是亮色(如,白),如果缺少了那么个乘法处理,影响将会是巨大的.
是bug吗?从公式上看AlphaBlend存在严重的错误,但ms不可能不知道,那就是我的用法问题,某些参数没设置正确?曾尝试了多种组合,未果.或者是我的用法不正确吧...
本文探讨了使用AlphaBlend函数处理PNG图片时遇到的问题及原因分析。AlphaBlend函数用于显示带有透明像素的位图,但在处理某些BMP文件时无法正常显示。文中详细解析了AlphaBlend的工作原理,并通过对比自定义Alpha混合公式的结果,发现了AlphaBlend函数可能存在的问题。
1087





