分类: LINUX
2010-08-12 11:13:14
R = G = B = 0.3R + 0.6G + 0.1B; //第二版改正后的公式
//第一版中的错误公式是 R = G = B = ( R + G + B ) / 3;
在实际编程应用中又可分为8位、16位和24位三种情况,下面进行一一介绍:
一、首先说最简单的24位点的转换,24位点的RGB均匀分布,所以分离和合成都较为简单,代码如下:
//===========8位转换(注:本函数只适用于全屏转换)===========
void RGB8_to_Gray()
{
int t; //临时变量
LPPALETTEENTRY Pal = (LPPALETTEENTRY) LocalAlloc( LPTR, sizeof( PALETTEENTRY ) * 256 );
//获取调色板
lpDDPal->GetEntries(0,0,256,Pal);
//转换
for(int i=0; i<256; i++)
{
t=( Pal[i].peRed * 3 + Pal[i].peGreen *6 + Pal[i].peBlue ) / 10; //第二版改正的地方
Pal[i].peRed=Pal[i].peGreen=Pal[i].peBlue=t;
}
//更新调色板
lpDDPal->SetEntries(0,0,256,Pe);
}
二、16位点的转换要麻烦一些,因其涉及到555和565两种色码格式,所以在转换前需要我们进行一些初始工作:
//=======16位转换============
BYTE RMove, GMove; //R和G移动到最低位需要的步数
//初始化数据,本函数在游戏初始时执行,仅执行一次
void Init()
{
if( Is555 ) //555模式 0rrrrrgggggbbbbb
{
RMove=10;
GMove=5;
}
else //565模式 rrrrrggggggbbbbb
{
RMove=11;
GMove=6;
/*注意:为什么这里GMove=6,因为565模式下G值有6位,如果用一个6位值和两个5位值相加除以3,得到的结果可能使5位溢出,所以我们要多移动一位即除以2*/
}
}
//16位点转换
WORD RGB16toGray(WORD sour)
{
WORD t;
WORD r, g, b;
r= sour >> RMove;
g= (GMask & sour) >> GMove;
b= BMask & sour;
t = (r*3+b*6+g)/10; //第二版改正的地方
return (t<<RMove)|(t<<GMove)|t;
}
三、8位点的转换和上面两种有比较大的差异,因为它的颜色是由调色板决定的,我们只有通过改变调色板来进行转换,先用lpDDPal->GetEntries()获得调色板,然后分别转换需要的调色板值,完成后用lpDDPal->SetEntries()更新即可,程序如下:
|