转载地址:http://www.cppblog.com/kredraw/archive/2008/09/19/62266.html

[Z]Alpha通道实现

图形学中,Alpha指的是除了颜色的三个分量(RGB)外的第四个分量,透明度
一个真彩色的像素由四个分量组成,RGBA
Alpha 的值在 0 到 1 之间,0表示完全透明,1 表示完全覆盖
 
图像A 和 图像B 组合而成的图像为 C
A: (R_Value_A, G_Value_A, B_Value_A, Alpha_A)
B: (R_Value_B, G_Value_B, B_Value_B, Alpha_B)
混合后的C 颜色为

R_Value_C = R_Value_A * Alpha_A + R_Value_B * Alpha_B
G_Value_C = G_Value_A * Alpha_A + G_Value_B * Alpha_B
B_Value_C = B_Value_A * Alpha_A + B_Value_B * Alpha_B

具体实现代码:

/**
 * alpha 值的范围为 0 ~ 255
 */

inline COLORREF AlphaPixel(UINT alpha, COLORREF clr1, COLORREF clr2)
{
    double k = (double)alpha / 256.0;
    double reverse_k = 1.0 - k;
    BYTE r = BYTE( GetRValue(clr2) * k + GetRValue(clr1) * reverse_k );
    BYTE g = BYTE( GetGValue(clr2) * k + GetGValue(clr1) * reverse_k );
    BYTE b = BYTE( GetBValue(clr2) * k + GetBValue(clr1) * reverse_k );
    return RGB(r, g, b);
}

透明度  50 %

  for ( int  i  =   0 ; i  <  size.cx; i ++ )
  {
  for ( int j = 0; j < size.cy; j++ )
  {
   pDC->SetPixel(i, j, AlphaPixel(255 / 2, RGB(255, 255, 255), dc.GetPixel(i, j)) );
  }// for j
 } //  for i

如此算法,如果是1024 * 768 的图,就很慢了,需要想办法优化

饿了,先去吃饭再研究~

吃完饭,继续

windows已经提供了 实现alpha混合的API
BOOL AlphaBlend(
HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest,  int nHeightDest,
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
BLENDFUNCTION blendFunction);
前面十个参数不用说了,主要在最后一个参数

typedef struct _BLENDFUNCTION
{
    BYTE   BlendOp;                    // BlendOp字段指明了源混合操作,但只支持AC_SRC_OVER,即根据源alpha值把源图像

叠加到目标图像上
                                             // OpenGL的alpha混合还支持其他的方式,如常量颜色源。
    BYTE   BlendFlags;                // 保留字段,必须是 0
    BYTE   SourceConstantAlpha; //
    BYTE   AlphaFormat;             // 0表示常量alpha值,AC_SRC_ALPHA表示每个像素有各自的alpha通道。
} BLENDFUNCTION;

BLENDFUNCTION结构控制源和目标位图的混合方式

如果AlphaFormat字段为0,源位图中的所有像素使用同样的常量alpha值,即SourceConstantAlpha字段中的值,该值实际上是0和255

,而不是0和1。这里0表示完
全透明,255表示完全不透明。目标像素以255-SourceConstantAlpha值作为alpha值。
如果AlphaFormat字段的值是AC_SRC_ALPHA,源设备表面的每个像素必须有各自的alpha通道。即,必须是32-bpp的物理设备上下文

,或是选中了32-bpp DDB和DIB
段的内存设备上下文。这些情况下,每个源像素有4个8位通道:红、绿、蓝和alpha。每个像素的alpha通道和SourceConstantAlpha

字段一起用于把源和目标混合
起来。实际用于计算的运算式如下:
Tmp.Red   = Src.Red   * SourceConstantAlpha / 255;
Tmp.Green = Src.Green * SourceConstantAlpha / 255;
Tmp.Blue  = Src.Blue  * SourceConstantAlpha / 255;
Tmp.Alpha = Src.Alpha * SourceConstantAlpha / 255;
Beta      = 255 – Tmp.alpha;
Dst.Red   = Tmp.Red   + Round((Beta * Dst.Red  )/255);
Dst.Green = Tmp.Green + Round((Beta * Dst.Green)/255);
Dst.Blue  = Tmp.Blue  + Round((Beta * Dst.Blue )/255);
Dst.Alpha = Tmp.Alpha + Round((Beta * Dst.Alpha)/255);

如果AlphaFormat字段的值是AC_SRC_ALPHA 的情况还没搞懂是什么意思

Feedback

# re: [Z]Alpha通道实现  回复  更多评论

2008-09-19 16:36 by lonkil

去掉浮点,alpha直接用0-255处理;
乘除用移位操作;
速度可能会快一点。

# re: [Z]Alpha通道实现  回复  更多评论

2008-09-19 17:49 by lonkil

我以前写的一个16位的混合。

//16位单像素的Alpha混合
GUI_COLOR PixelAlpha_565(U16 sour, U16 desc, U8 nAlpha )
{
U32 R=0,G=0,B=0,R1=0,G1=0,B1=0;
GUI_COLOR clr=0,clr1=0;
static int n=0;
//提取GUI_COLOR的RGB
R = ( sour >> 11 ) & 0x1f;
G = ( sour >> 5 ) & 0x3f;
B = sour & 0x1f;

R1 = ( desc >> 11 ) & 0x1f ;
G1 = ( desc >> 5 ) & 0x3f;
B1 = desc & 0x1f;

//混合
R = (( ( R - R1 ) * nAlpha ) >> 8 ) + R1;
G = (( ( G - G1 ) * nAlpha ) >> 8 ) + G1;
B = (( ( B - B1 ) * nAlpha ) >> 8 ) + B1;

clr = ( B << 19 ) | ( G << 10 ) | R<<3;

return clr;
}

其实混合算法优化还是值得研究的,如果不在windows下就没有AlphaBlend可用了。

# re: [Z]Alpha通道实现  回复  更多评论

2008-09-19 20:30 by 没画完的画

感谢 lonkil 提出的建议.

# re: [Z]Alpha通道实现  回复  更多评论

2008-09-19 21:29 by 陈梓瀚(vczh)

用汇编,将一个寄存器的四个字节XXXX分别写成0R0G,R和G就能一起算了。如此类推。

好象是4年前吧,我用delphi实现过一个,爆快。

# re: [Z]Alpha通道实现回复  更多评论

2008-09-19 21:30 by 陈梓瀚(vczh)

AlphaBlend是不能用的,他那个blend function不是完整的,需要事先做点儿事情。

转载-Alpha通道实现相关推荐

  1. (4)关于Alpha通道问题

    其实,我还是不理解,我还是先把我目前懂得和觉得有用的东西先存下来 =================================================================== ...

  2. 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题

    #include <windows.h> #include <GL/glut.h> #include <GL/glaux.h> #include <stdio ...

  3. 窗体的Alpha通道透明色支持

    参考: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2190768 Windows 2000后,为了支持类似MAC界面的Alpha通道混合效果,提 ...

  4. Alpha通道原理及实现方法

    ALPHA是什么?在图形学中,ALPHA指的是除了颜色的三个分量(RGB)外的第四个分量:透明度.所以,一个真彩色(指利用RGB分量合成颜色)的像素就变成由四个分量组成:R.G.B.A.在我们的讨论里 ...

  5. [原]BMP位图 转换 透明 TGA图像 - 增加 alpha通道 -TGA文件格式初解

    最近做一个将文字转换为图片做视频叠加字幕的软件,大家都知道VB的图像控件Picture Box只能输出BMP格式位图,自然我的软件是用Picture Box做图像输出的也不例外,但是客户要求要输出带a ...

  6. Alpha通道是什么意思,和rgb通道有什么区别

    Alpha通道是什么意思,和rgb通道有什么区别 Alpha通道: 阿尔法通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明.不透明和半透明区域,其中白表示不透明,黑表示 ...

  7. 使用IconWorkshop制作带alpha通道的位图

    使用IconWorkshop制作带alpha通道的位图 引自:http://www.cnblogs.com/liqilei/archive/2011/01/26/1945787.html 最近在项目中 ...

  8. 使用opencv中的merge()函数为BGR图像添加alpha通道

    先上代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # 图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 # 图像处理 ...

  9. unity加载sprite_Unity 分离贴图 alpha 通道实践

    引言 在做手机游戏时可能会遇到这些问题: UI 同学天天抱怨 iOS 上一些透明贴图压缩后模糊不堪 一些古早的 Android 手机上同样的贴图吃内存超过其他手机数倍,游戏经常闪退 这篇文章给出了一种 ...

最新文章

  1. 错误类型3错误:活动类{}不存在
  2. Matchme php script_apache php-fpm Primary script unknown\n - TechBlog
  3. 如何读取csv文件中第n行数据python-python数据处理之如何选取csv文件中某几行的数据...
  4. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
  5. 《当程序员的那些狗日日子》(六十一)美丽的天际
  6. C#快速导入海量XML数据至SQL Server数据库
  7. Mac搜索技巧|高级设置搜索条件/属性/类型
  8. 论文阅读笔记——个体识别研究中的计算机辅助照片匹配:以塞伦盖蒂猎豹为例
  9. 计算机技术证明数学定理,数学要项定理公式证明辞典
  10. 学校计算机考试系统故障,解决在线考试系统设计的常见问题
  11. PS与CSS字间距转换
  12. ROS运行管理之launch文件
  13. 【机器学习基础】泛化能力、过拟合、欠拟合、不收敛、奥卡姆剃刀原则
  14. 青少年CTF-Web-CheckMe01
  15. 人人商城互动直播(与通信服务器连接失败)
  16. 威眼(WeaView)企业计算机监管系统如何安装客户端和日常使用
  17. 刀~~~~~~~~~~~~
  18. 在 Laravel 中使用 Tailwind CSS
  19. 华为MUX VLAN
  20. 如何安装java环境和如何配置java环境

热门文章

  1. 不知道怎么编辑图片?只需三步就可以学会
  2. 花卉店家端隐私权政策
  3. linux7 epel源,CentOS 7 安装EPEL源
  4. bzoj 1017 魔兽地图DotR
  5. 【python】给视频添加背景音乐
  6. distinct 关键字
  7. Linux文件权限设置(chmod命令)
  8. 基于机器学习的协同创新设计框架-香水瓶设计
  9. 基于JAVA智能化车辆管理综合信息平台计算机毕业设计源码+系统+数据库+lw文档+部署
  10. ARM64移动处理器解惑 iphone5s