您的位置:首页 > 其它

如何获得RGB的各个颜色值

2017-04-10 11:57 429 查看
作者:唐宏冰

主页:http://jmtk.xiloo.com

作品:决战单词——让我们告别背单词的苦恼!

邮件:hb_t@sohu.com

一、在C或Pascal中的实现方法。

因为C语言和Pascal语言能支持计算机比较底层的操作,提供了位运算和指针,所以实现起来相当的容易和高效。

1、用位运算来实现。

我们只要通过位运算分别取出32位色彩值的第一字节、第二字节和第三字节即可。Red、Green和Blue所分别对应这三个字节。例如C语言中可以是这样的:

/*定义位运算所需的掩码*/

#define MASK_R 0xFF

#define MASK_G 0xFF00

#define MASK_B 0xFF0000

/*函数的第一个形参是32位长整型色彩值,其余的参数分别返回红、绿、蓝的色彩值。*/

void GetRGB(long int color,char *r,char *g,char *b)

{

*r=color & MASK_R; //取出第一字节给红色

*g=(color & MASK_G)>>8; //取出第二字节给绿色

*b=(color & MASK_B)>>16;//取出第三字节给蓝色

}

2、用指针运算来实现。使指针指向不同的内存空间来获得红绿蓝的色彩值。

void GetRGB(long int color,char *r,char *g,char *b)

{

long int *pcolor;

char * ptemp; //声明一个字符指针,只能指向一个字节。

pcolor=&color;

ptemp=(char *)pcolor; //临时指针指向长整型色彩值的第一位

*r=*ptemp; //第一位即为红色

*g=*(++ptemp); //指向第二个字节,得到绿色

*b=*(++ptemp); //指向第三个字节,得到蓝色

}

二、在Basic这类没有指针、位运算的语言中的实现。

由于Basic语言的先天不足,没有C语言和Pascal语言的指针和位运算,实现起来好像比较因难,最重要的是效率低下。例如,常常是这样:

'过程的第一个参数为颜色总量,其它三个参数返回红绿蓝的值。

Private Sub GetRGB(lColor As Long, bRed As Byte,bGreen As Byte, bBlue As Byte) 

    bRed = lColor Mod 256

    bBlue = lColor \ 65536

    bGreen = (lColor And 65535) \ 256

   

End Sub

那么,有没有效率高、好理解的方法呢?当然有!我们需要一个Windows API函数来帮忙,它的原形是:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

该函数的作用是把一段内存中的数据拷贝到另一段内存中,Source表示源,Destination表示目标,Length表示拷贝的字节长度。我们由这个函数自然会想到,何不把一个32位色彩值拷贝到一个由4个Byte构成的结构中呢,那么这4个Byte的前3个变量就分别是Red、Green和Blue的值了。例如:

'首先定义一个由4个Byte变量构成的数据类型

Private Type Color32

    bRed As Byte

    bGreen As Byte

    bBlue As Byte

    bUnuse As Byte

End Type

Private Sub GetRGB(lColor As Long, bRed As Byte, bGreen As Byte, bBlue As Byte)

    Dim TempColor32 As Color32

    

    CopyMemory TempColor32, lColor, 4 '拷贝4个字节到结构中

    With TempColor32

        bRed = .bRed

        bGreen = .bGreen

        bBlue = .bBlue

    End With

        

End Sub

用这种方法来实现,相当的直观,更符合思维习惯,执行的速度也更快些,何乐而不为呢?其实这种方法给了我们一个很好的启示,凡是那些需要从某种类型的变量中取出一部分值的操作都可向这样实现了。

本文中的C程序段在TC3.0下通过,Basic程序段在VB6.0下通过。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: