二、Windows图形处理—设备内容(关于色彩)
如果视讯显示卡仅显示黑色图素和白色图素,则每个图素只需要内存中的一位。彩色显示器中每个图素需要多个位。位数越多,色彩越多,或者更具体地说,可以同时显示的不同色彩的数目等于2的位数次方。
「Full-Color」视讯显示器的分辨率是每个图素24位-8位红色、8位绿色以及8位蓝色。红、绿、蓝即「色光三原色」。混合这三种基本颜色可以生成许多其它的颜色,您通过放大镜看显示屏,就可以看出来。
「High-Color」显示分辨率是每个图素16位-5位红色、6位绿色以及5位蓝色。绿色多一位是因为人眼对绿色更敏感一些。
显示256种颜色的显示卡每个图素需要8位。然而,这些8位的值一般由定义实际颜色的调色盘组织的。我会在 第十六章详细地讨论它们。
最后,显示16种颜色的显示卡每个图素需要4位。这16种颜色一般固定分为暗的或亮的红、黑、蓝、青、紫、黄、两种灰色。这16种颜色要回溯到老式的IBM CGA。
碉有在某些怪异的程序中才需要知道视讯显示卡上的内存是如何组织的,但是GetDeviceCaps使程序写作者可以知道显示卡的储存组织以及它能够表示的色彩数目,下面的呼叫传回色彩平面的数目:
iPlanes = GetDeviceCaps (hdc, PLANES) ;
下面的呼叫传回每个图素的色彩位数:
iBitsPixel = GetDeviceCaps (hdc, BITSPIXEL) ;
大多数彩色图形显示设备使用多个色彩平面或每图素有多个色彩位的设计,但是不能同时一齐使用这两种方式;换句话说,这两个呼叫必有一个传回1。显示卡能够表示的色彩数可以用如下公式来计算:
iColors = 1 << (iPlanes * iBitsPixel) ;
这个值与用NUMCOLORS参数得到的色彩数值可能一样,也可能不一样:
iColors = GetDeviceCaps (hdc, NUMCOLORS) ;
我提到过,256色的显示卡使用色彩调色盘。在那种情况下,以NUMCOLORS为参数时,GetDeviceCaps传回由Windows保留的色彩数,值为20,剩余的236种颜色可以由Windows程序用调色盘管理器设定。对于High-Color和True-Color显示分辨率,带有NUMCOLORS参数的GetDeviceCaps通常传回-1,这样就无法得到需要的信息,因此应该使用前面所示的带有PLANES和BITSPIXEL值的iColors公式。
在大多数GDI函数呼叫中,使用COLORREF值(只是一个32位的无正负号长整数)来表示一种色彩。COLORREF值按照红、绿和蓝色的亮度指定了一种颜色,通常叫做「RGB色彩」 。32位的COLORREF值的设定如图5-4所示。
注意最前面是标为0的8个位,并且每种原色都指定为一个8位的值。理论上,COLORREF可以指定二的二十四次方种或一千六百万种色彩。
这个无正负号长整数常常称为一个「RGB色彩」。Windows表头文件WINGDI.H提供了几种使用RGB色彩值的宏。RGB宏要求三个参数分别代表红、绿和蓝值,然后将它们组合为一个无正负号长整数:
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r) | \
((WORD)((BYTE)(g)) << 8)) | \
(((DWORD)(BYTE)(b)) << 16)))
注意三个参数的顺序是红、绿和蓝。因此,值:
RGB (255, 255, 0)
是0x0000FFFF,或黄色(红色和绿色的合成)。当所有三个参数设定为0时,色彩为黑色;当所有参数设定为255时,色彩为白色。GetRValue、GetGValue和GetBValue宏从COLORREF值中抽取出原色值。当您在使用传回RGB色彩值的Windows函数时,这些宏有时会很方便。
在16色或256色显示卡上,Windows可以使用「混色」来模拟设备能够显示的颜色之外的色彩。混色利用了由多种色彩的图素组成的图素图案。可以呼叫GetNearestColor来决定与某一色彩最接近的纯色:
crPureColor = GetNearestColor (hdc, crColor) ;