将RGB值转换为灰度值的简单算法

转载 2005年02月25日 17:17:00
  使场景或精灵以灰度的形式显示,这是一般游戏制作中常常用到的效果,如:战棋游戏中当一个角色被使用过后,通常就会变成灰色,代表本回合已不能行动了;《仙剑》中回忆彩蝶的部分是用整屏的灰色来表现的?(记的不太清楚,太久了^_^);还有很多很多例子……
  将RGB值转换为灰度的过程应该是在程序中实现的(至少我是这么认为的)。其实这是非常简单的,基本原理就是将一个点的RGB值分开来求和,然后除以3,把得到的值再分别付给RGB,用公式表示如下:

R = G = B = 0.3R + 0.6G + 0.1B; //第二版改正后的公式
//第一版中的错误公式是 R = G = B = ( R + G + B ) / 3;

  在实际编程应用中又可分为8位、16位和24位三种情况,下面进行一一介绍:
  一、首先说最简单的24位点的转换,24位点的RGB均匀分布,所以分离和合成都较为简单,代码如下:


//=======24位转换============
int gMask=0x00ff00; //绿色掩码
int bMask=0x0000ff; //兰色掩码

int RGB24toGray(int sour)
{
    int r,g,b,t; //临时变量

    r=(sour>>16);
    g=(sour & gMask) >>8;
    b=sour & bMask;
    t=(r*3+g*6+b)/10; //第二版改正的地方

    return (t<<16)|(t<<8)|t;
}

  二、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()更新即可,程序如下:

//===========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位转换已经过测试,而其余两种尚未测试,如果各位发现有问题请及时指正。另:我曾试图用汇编对16转换进行优化,但由于本人的汇编功底实在过于拙劣,经汇编改写后的代码效率不但没有提高,反而有小幅下降,所以如果有人对其16位转换进行优化后,请务必发给在下一份,不胜感激!

十进制转换为二进制的简便算法

/***************************************************************十进制转换为二进制的简单算法**********************...
  • twltdwx
  • twltdwx
  • 2008年05月15日 20:08
  • 1143

将 varchar 值转换为 JDBC 数据类型 DATE 时发生错误。

问题是: 我是这样解决的  : 网上的 转型方法 并不好使 ,我想了想 可能是由于返回值是String  我 就成功的解决错误了  。。下面是关于...
  • sz457763638
  • sz457763638
  • 2015年01月08日 12:43
  • 3754

原始数据到CT值的转换

用从DICOM文件中读取的rescaleslope值和rescale intercept值可以将每个像素的灰度值转换成CT值。 Hu=pixel_val*rescale_slope+resc...
  • yunzhaoqiang
  • yunzhaoqiang
  • 2017年03月15日 09:57
  • 2073

将VARCHAR值""转换为数据类型为"int"的列时发生语法错误!的解决方法

将VARCHAR值""转换为数据类型为"int"的列时发生语法错误.从一个Edit的编辑框中获取m_name,m_id,m_old.三个变量.m_id,m_old是int的.m_name是CStrin...
  • analysefirst
  • analysefirst
  • 2008年08月27日 08:58
  • 3623

Hibernate错误记录(二): 将 nvarchar 值转换为 JDBC 数据类型 TIMESTAMP 时发生错误。

Hibernate结合SQlSever2012做查询操作,在出生日期发生的类型转换错误: 以下是数据库设计: 如图birthday数据类型为date; 以下是报错信息: Caused ...
  • mifan649191
  • mifan649191
  • 2017年08月17日 22:57
  • 499

类型"string"的值无法转换为"System.Drawing.Color"

代码如下: string strC="#C0FFFF"; Label1.BackColor=strC; 报错为:类型"string"的值无法转换为"System.Drawing.Color" 解决方法...
  • xiong1000
  • xiong1000
  • 2006年12月12日 17:04
  • 2103

com.microsoft.sqlserver.jdbc.SQLServerException: 将 IDENTITY 转换为数据类型 numeric 时出现算术溢出错误。

SQL Server 2008 R2>>>服务器上的项目一直没有问题,但是突然之间开始报错,以下是报错信息: com.microsoft.sqlserver.jdbc.SQLServerExcepti...
  • zlq1262786810
  • zlq1262786810
  • 2016年01月04日 16:20
  • 1147

将 varchar 值 'null' 转换为数据类型为 int 的列时发生语法错误。

 sldfinsert into schoolInfo(schoolId,schoolName,principal,schoolSize,area,telephone,introduce,state)...
  • zhq426
  • zhq426
  • 2007年08月01日 19:30
  • 3817

Jsp中EL表达式将null自动转换为字符串的用处之一

当我们在某个网站填写注册信息的时候,如果填写的信息有误,网站通常都会跳回注册页面。 下面是一般的写法:        姓名:            但是,网站在跳回到注册页面的时候,...
  • LonelyRoamer
  • LonelyRoamer
  • 2012年05月23日 15:15
  • 4598

java读取图像的rpg以及灰度值,可以对rgb进行修改后输出新图像

java读取图像的rpg以及灰度值,可以对rgb进行修改后输出新图像/** *java读取图像的rpg以及灰度值,可以对rgb进行修改后输出新图像 */ File file = new...
  • w305172521
  • w305172521
  • 2015年12月28日 10:44
  • 3253
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:将RGB值转换为灰度值的简单算法
举报原因:
原因补充:

(最多只允许输入30个字)