请教alpha通道实现透明度的原理

Fairchild_Lhy 2014-10-02 02:19:57
最近在研究BMP位图的格式,希望不利用任何已封装好的类,而是自己从底层开始探究,自己设计一个类来对BMP位图进行解析。

在研究到32位BMP的时候,接触到了Alpha通道的概念,查了下资料,了解到这个Alpha通道值是用于设置图片透明度的。

对于32位的BMP,每个像素的数据就占了4字节。
用UE打开,假设在文件中以小端法存放数据:55 66 77 88
对应过来就是Blue 55, Green 66,Red 77, Alpha 88。

我在实现绘制的时候,用的SetPixel(dc, x, y, RGB(r, g, b))这个函数,但是这个函数只和RGB值相关,也就是没有透明度的概念。
我想知道,从最底层出发,有没有专门设置像素点透明度的函数。

另外,看到有一个帖子上说:
透明度的原理是:
X = (X*Alpha +127) / 255;
其中X可以是R,G,B
对R,G,B,A都做如上计算处理,就实现了Alpha通道的透明度实现。

那么,如果以上算法属实,是不是就说明了其实每一个像素的表示,只与RGB值有关,所谓的Alpha通道透明,只是提供了一种算法(上面所述的算法),来改变RGB的值,达到所谓“透明”的效果呢?

由于对“透明”概念的理解还太模糊,希望能得到比较全面的回答,谢谢~

...全文
1489 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Fairchild_Lhy 2014-10-06
  • 打赏
  • 举报
回复
引用 6 楼 Idle_ 的回复:
[quote=引用 5 楼 Fairchild_Lhy 的回复:] 感谢你的回答,混合比例我已经有一定的了解了,那么,在实际的带有Alpha通道的32位BMP位图里面,是怎样存储一个像素点的数据的呢,就是说我希望windows能按我设置的透明度来读取并显示出图片,那么我用二进制打开BMP,里面的像素点数据应该如何写,按小端存放的表示一个像素的4字节顺序是A B G R还是B G R A? 最好能给一个windows系统能识别的32位BMP给我,我用UE打开研究研究,谢谢了。
32位bmp和24位bmp没多大区别,windows可以识别的bmp32格式很简单: BITMAPFILEHEADER BITMAPINFOHEADER Scanline0 Scanline1 .... 其中: BITMAPINFOHEADER.biBitCount=32; BITMAPINFOHEADER.biCompression=BI_RGB; 每条Scanline长度=BITMAPINFOHEADER.biWidth*4,和24bit bmp不同的是scanline之间没有对齐用的gap字节,因为scanline中每pixel本来就占了一个DWORD,字节顺序是B,G,R,A, 不过R,G,B的值是预乘了A的,比如A=200时白色是R=G=B=200而不是R=G=B=255。[/quote] 原来这样,我明白了,谢谢了!
  • 打赏
  • 举报
回复
Alpha混合公式如下: R(C)=(1-alpha)*R(B)+alpha*R(A) G(C)=(1-alpha)*G(B)+alpha*G(A) B(C)=(1-alpha)*B(B)+alpha*B(A)
阿呆_ 2014-10-03
  • 打赏
  • 举报
回复
引用 5 楼 Fairchild_Lhy 的回复:
感谢你的回答,混合比例我已经有一定的了解了,那么,在实际的带有Alpha通道的32位BMP位图里面,是怎样存储一个像素点的数据的呢,就是说我希望windows能按我设置的透明度来读取并显示出图片,那么我用二进制打开BMP,里面的像素点数据应该如何写,按小端存放的表示一个像素的4字节顺序是A B G R还是B G R A? 最好能给一个windows系统能识别的32位BMP给我,我用UE打开研究研究,谢谢了。
32位bmp和24位bmp没多大区别,windows可以识别的bmp32格式很简单: BITMAPFILEHEADER BITMAPINFOHEADER Scanline0 Scanline1 .... 其中: BITMAPINFOHEADER.biBitCount=32; BITMAPINFOHEADER.biCompression=BI_RGB; 每条Scanline长度=BITMAPINFOHEADER.biWidth*4,和24bit bmp不同的是scanline之间没有对齐用的gap字节,因为scanline中每pixel本来就占了一个DWORD,字节顺序是B,G,R,A, 不过R,G,B的值是预乘了A的,比如A=200时白色是R=G=B=200而不是R=G=B=255。
Fairchild_Lhy 2014-10-02
  • 打赏
  • 举报
回复
引用 1 楼 Idle_ 的回复:
没有专门设置像素alpha的API,因为包含alpha的bmp都是DIB,所以你可以自己设置scanline中相关位置的值。 所谓透明,其实就是前景色和背景色的混合,比如alpha=127时,显示出来的最终像素颜色就是图片中相应像素颜色的50%+原始背景中相应像素颜色的50%,alpha值越大,前景色占的比重越大,alpha=255时就是不透明(全为前景色),alpha=0时就是全透明(全为背景色)。 Windows中显示32位bmp的函数是AlphaBlend(),但是对32位bmp像素颜色有特殊要求,必须是预乘好的颜色,即像素的r,g,b颜色并不是原始R,G,B,而是r=R*A/255, g=G*A/255, b=B*A/255。
哦,原来是这样,但是为什么有的地方是用255表示全透明呢? 我参考的这里: http://wenku.baidu.com/link?url=bzr8t4KV2YQPXVCQC41uZzaEEZLke4yYmBhnToZGGoEqbk_eAmTI-qi4DCs8wgr7UewOCrVabYC-Hq_kLki-mF6BmJiXzMIRJi8sEV4szq7 里面的公式是这样的: 混合算法目前在游戏上常用到的算法是AlphaBlend。计算公式如下 假设一幅图象是A,另一幅透明的图象是B,那么透过B去看A,看上去的图象C就是B和A的混合图象,设B图象的透明度为alpha(取值为0-1,1为完全透明,0为完全不透明),Alpha混合公式如下: R(C)=(1-alpha)*R(B)+alpha*R(A) G(C)=(1-alpha)*G(B)+alpha*G(A) B(C)=(1-alpha)*B(B)+alpha*B(A) 到底什么时候用255表示全透明,什么时候表示不透明啊
阿呆_ 2014-10-02
  • 打赏
  • 举报
回复
没有专门设置像素alpha的API,因为包含alpha的bmp都是DIB,所以你可以自己设置scanline中相关位置的值。 所谓透明,其实就是前景色和背景色的混合,比如alpha=127时,显示出来的最终像素颜色就是图片中相应像素颜色的50%+原始背景中相应像素颜色的50%,alpha值越大,前景色占的比重越大,alpha=255时就是不透明(全为前景色),alpha=0时就是全透明(全为背景色)。 Windows中显示32位bmp的函数是AlphaBlend(),但是对32位bmp像素颜色有特殊要求,必须是预乘好的颜色,即像素的r,g,b颜色并不是原始R,G,B,而是r=R*A/255, g=G*A/255, b=B*A/255。
Fairchild_Lhy 2014-10-02
  • 打赏
  • 举报
回复
引用 4 楼 relaxisland 的回复:
第一种情况: 你把 最终要显示的像素都计算好了 #对于计算后的像素来说, 显示的透明度其实是不透明的 第二种情况: 你指定像素 和 透明度 系统可以帮你计算好,然后再显示的。
感谢你的回答,混合比例我已经有一定的了解了,那么,在实际的带有Alpha通道的32位BMP位图里面,是怎样存储一个像素点的数据的呢,就是说我希望windows能按我设置的透明度来读取并显示出图片,那么我用二进制打开BMP,里面的像素点数据应该如何写,按小端存放的表示一个像素的4字节顺序是A B G R还是B G R A? 最好能给一个windows系统能识别的32位BMP给我,我用UE打开研究研究,谢谢了。
relaxisland 2014-10-02
  • 打赏
  • 举报
回复
第一种情况: 你把 最终要显示的像素都计算好了 #对于计算后的像素来说, 显示的透明度其实是不透明的 第二种情况: 你指定像素 和 透明度 系统可以帮你计算好,然后再显示的。
relaxisland 2014-10-02
  • 打赏
  • 举报
回复
这个,你要搞清楚2种情况的区别 1 你自己写alpha通道实现 前景图片A和背景图片B的混合 这时候你想用 0到255,还是0到1, 就看你的公式怎么写了 #0 到255 算出来的结果还是要除以255的 所以 说到底就是2中颜色的混合比例 2 你自己弄一张图片,希望windows能按你设定的透明比例来 显示你的图片 32位图片是RGBA, 各占8个bit 因此,这时候alpha必须用0到255, 255 表示全透明 默认值0表示 完全不透明

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧