[原创] 关于 AlphaBlend 函数
来源:互联网 发布:linux退出管理员权限 编辑:程序博客网 时间:2024/05/22 07:47
最近工作中写个工具软件要支持带Alpha通道的PNG图,使用libpng成功读取出了PNG的数据,但是用AlphaBlend进行显示的时候却遇到了问题。
在网上搜索了一下,好像很多前辈使用这个函数都不成功,最后得出的一致结论是AlphaBlend除了SourceConstantAlpha不等于255时可用以外,对带Alpha通道的图是显示不了的,需要自己写Alpha混合算法。因为是搞嵌入式开发,Alpha混合算法倒是很熟练了,所以也没多想就自己写了一个。回过头想想觉得还是有问题,难道微软会忽悠我们?后来仔细看了一下MSDN,恍然大悟。
微软的运算公式为:
Dst.Red = Src.Red + (1 - Src.Alpha) * Dst.Red Dst.Green = Src.Green + (1 - Src.Alpha) * Dst.Green Dst.Blue = Src.Blue + (1 - Src.Alpha) * Dst.Blue
注意,以上公式中 Src.Alpha 已经转换成了浮点数,并已除以 255 ,所以取值范围是 0 ~ 1.0 。
我们都知道,正确的Alpha混合的公式是:
Dst.Red = Src.Red * Src.Alpha + (1 - Src.Alpha) * Dst.Red Dst.Green = Src.Green * Src.Alpha + (1 - Src.Alpha) * Dst.Green Dst.Blue = Src.Blue * Src.Alpha + (1 - Src.Alpha) * Dst.Blue
由此可知,只要将Src.Red, Src.Green, Src.Blue先乘以Src.Alpha就可以正常进行Alpha混合了。经过试验,证明了这样处理是可以正确进行Alpha混合的。以前混合不正确是由于没有将原图的各个分量先预乘Alpha值,相加后很容易就溢出了,所以混合出来的图除了Alpha值为0的像素可以正常以外,其他像素都偏白。
微软这样处理的目的可能是考虑到Alpha混合的效率,可以在每个像素Alpha混合时少做三次乘法运算,但是他又引入了浮点运算,这点又降低了效率。下面给出我的Alpha混合的公式以供各位参考,以下所有值都是0 ~ 255的8位无符号整数。
Dst.bytRed = (BYTE)(((int)Src.bytRed * (int)Src.bytAlpha + (255 - (int)Src.bytAlpha) * (int)Dst.bytRed) / 255);Dst.bytGreen = (BYTE)(((int)Src.bytGreen * (int)Src.bytAlpha + (255 - (int)Src.bytAlpha) * (int)Dst.bytGreen) / 255);Dst.bytBlue = (BYTE)(((int)Src.bytBlue * (int)Src.bytAlpha + (255 - (int)Src.bytAlpha) * (int)Dst.bytBlue) / 255);
- [原创] 关于 AlphaBlend 函数
- 关于AlphaBlend函数使用时遇到的问题
- AlphaBlend 函数(Platform SDK)
- StretchBlt()与AlphaBlend()函数
- AlphaBlend
- AlphaBlend
- AlphaBlend
- AlphaBlend
- 关于TransparentBlt和AlphaBlend的不同
- 关于提高AlphaBlend效率的思考
- 关于提高AlphaBlend效率的思考
- 关于提高AlphaBlend效率的思考
- AlphaBlend/StretchBlt/BitBlt 三个函数介绍
- 关于CImage和AlphaBlend的透明PNG图片显示问题
- 关于 AlphaBlend 和 32bpp 的反锯齿图标
- Delphi中图像混合透明的函数AlphaBlend的使用
- ORACLE几个关于工作日数的函数(原创)
- (原创)关于构造函数及参数执行顺序说明(c#)
- design principle:java 回调与委派/委托机制
- html中嵌入flash
- Linux下学习C语言的路线
- “低头族”——停下来,享受美丽
- eclipse关于项目的详细介绍
- [原创] 关于 AlphaBlend 函数
- Matlab计算机视觉/图像处理工具箱推荐
- uva 10791 - Minimum Sum LCM(分解因子)
- 熟读bug三百条(附典型案例下载)
- 收集ios开源框架
- Cocos2d-x 开发 点击交互的四种处理
- 在VC++中读写INI文件
- ActionContext和ServletActionContext小结
- poj3278(广搜剪枝)