网页功能: 加入收藏 设为首页 网站搜索  
基于256色的Alpha混合方法(查表法)的实现方法
发表日期:2006-08-20作者:[转贴] 出处:  

  在网站上看到过很多Alpha混合计算的相关文档,其中不乏经典之作,但大多数都是基于16位显示模式下的,而256色的却很少有人谈及。所以,决定写一个基于256色的Alpha混合算法的详细实现方法。以帮助那些初学者,给他们一点点小小的灵感:)

  首先,假设你已经有了一个调色板,我们将根据这个调色板来计算和创建一个Alpha_Map[256][256]的二维整形数组,这个数组用来存放混合后的颜色对应于(或近似)这个调色板中的索引值。

  然而,我们如何获得这个索引值呢?这就需要进行一个求近似值的函数Find_Index(),这个函数主要负责根据给定的三个基色的值,从调色板中找到相同颜色或最接近颜色的索引值,并返回这个索引值。此函数还需要一个结构:BEST_FIT,它的定义是:

typedef struct BEST_FIT_TYP
{
    int sum; // 累加值
    int index; // 索引值
}BEST_FIT;

有了这个结构,就可以写Find_Index()函数了,函数原形如下:

int Find_Index(BYTE R, BYTE G, BYTE B, PALETTEENTRY *palette)
{
    int rn = 0, // Red差值分量
    gn = 0, // Green差值分量
    bn = 0; // Blue差值分量

    BEST_FIT best;
    best.sum = 100; // 初始赋给累加值一个最大值
    best.index = 0; // 初始化索引值

    for (int index = 0; index < 256; index++)
    {// 遍历调色板
        rn = palette[index].peRed - R; // 计算差值,以下相同
        if (rn < 0)
            rn = -rn; // 求绝对值,以下相同
        gn = palette[index].peGreen - G;
        if (gn < 0)
            gn = -gn;
        bn = palette[index].peBlue - B;
        if (bn < 0)
            bn = -bn;

        if (best.sum > (rn + gn + bn)) // 判断三个分量的累加值是否大于原来的累加值
        {
            best.sum = rn + gn + bn; // 更新累加值
            best.index = index; // 更新索引值
            if (0 == best.sum) // 如果累加值为零,即颜色匹配
            {
                return(best.index); // 返回索引值
                break;
            }// end if
        }// end if

    }// end for
    return(best.index); // 返回近似值
}

这个函数可以返回一个索引值,这样我们就能利用这个索引值建立Alpha_Map[256][256]查色表了。

现在我们终于能够开始建立查找表了,这是一个50%的Alpha混合函数,如果需要的话,你可以改变混合级别。

首先,在这里需要说明一下函数的公式由来,以方便读者理解。

先说说PALETTEENTRY这个结构,结构定义如下:

typedef struct tagPALETTEENTRY {
    BYTE peRed;
    BYTE peGreen;
    BYTE peBlue;
    BYTE peFlags;
} PALETTEENTRY;

这个结构分别用3个字节表示RGB三基色的值。

我们可以用这三个基色值进行50%的Alpha混合运算。公式如下所示:

  srcRGB:原点颜色值
  destRGB:目标点颜色值
  RGB:结果
  alpha:混合级数,开始为一个0--1之间的浮点数,我们一般将它转换为整形进行计算。因为这里是50%的混合运算,所以它的值就是0.5。
  Alpha混合基本公式:
    RGB = 0.5 * srcRGB + (1 – 0.5) * destRGB;
    将其进行化简,就得到了下式:
    RGB = 0.5 * (srcRGB + destRGB);
    乘以0.5就相当于向右移1位,所以最后的公式就是:
    RGB = (srcRGB + destRGB) >> 1;

根据这个公式,就能够获得一个50%的Alpha混合的RGB的色彩值,在这里由于是用调色板做的,所以,RGB要分开来计算。

下面就是初始化Alpha_Map[256][256]的函数,里面调用了前面的Find_Index()函数;

void Alpha_Init(PALETTEENTRY *palette)
{
    for (int index1 = 0; index1 < 256; ++index1)
    for (int index2 = 0; index2 < 256; ++index2)
    {
        R = (palette[index1].peRed + palette[index2].peRed) >> 1;
        G = (palette[index1].peGreen + palette[index2].peGreen) >> 1;
        B = (palette[index1].peBlue + palette[index2].peBlue) >> 1;

        Alpha_Map[index1][index2] = Find_Index(R, G, B, palette);;
    }// end for
}

  这样,我们便完成了基于256色的Alpha混合运算的查找表,当我们需要进行Alpha混合运算的时候,直接可以用源色和目的色的索引值作为数组下标,来从这个表中找到一个近似的颜色。

  本人第一次发表这类文档,有不足之处和疏漏的地方,还望高手指教,强烈需求一起学习和研究。我的邮箱是:
song_zp@126.com。欢迎来信!

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 基于256色的Alpha混合方法(查表法)的实现方法
本类热点文章
  在DirectX 8 中进行2D渲染
  DirectDraw打造极速图形引擎(一)
  用窗口模式运行游戏
  DirectDraw编程基础
  Windows的位图alpha混合技术
  再谈GDI模式作图
  终极优化你的游戏——使用脏矩形技术
  D3D8里面的2D图形编程
  全屏模式
  对2D游戏引擎设计的一些思考
  DirectX8中的二维图形高级技巧
  使用标准GDI实现游戏品质的动画系统
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00605