前面也有简单使用了颜色相关的函数,本篇详细讲讲SimpleCG里的与颜色相关操作。大家从小就知道水彩笔可以用黄色加上蓝色调出绿色。颜料可以通过三种基础颜料根据不同比例调制出各种颜色。同样在计算机中我们通常也通过颜色的三个分量来合成千变万化的颜色。其中最普遍的接触最多的是RGB模型,R代表红色,G代表绿色,B代表蓝色。不过为了方便不同的场景下使用,可以采用不同的模型对颜色进行表达,下面分别对SimpleCG支持的颜色模型进行介绍。
一、最简单使用最普遍的RGB模型
类似于小时候颜料的混合,RGB也用三种不同的基色进行混合输出,达到显示不同颜色的效果。不同的是RGB模型是光线的输出,颜料的CMYK模型是颜料对光线的吸收。在windows中对RGB颜色有原生支持,可以直接用COLORREF 类型定义。该类型为32位整数,最高位字节不用,另外三个字节代表R、G、B三个分量,可以直接用32位整型变量定义颜色0x00bbggrr。windows也提供了RGB宏用于设置颜色RGB分量,例如如下代码都是定义一个红色的变量:
COLORREF nRed1=RGB(255,0,0);
COLORREF nRed2=0x0000FF;
如果要从颜色变量获取颜色分量,可以使用GetRValue、GetGValue、GetBValue三个宏。例如如下代码分别获取颜色nColor的三个分量:
int r = GetRValue(nColor);
int g = GetGValue(nColor);
int b = GetBValue(nColor);
三个分量取值范围分别是(0~255),有256种可能,所以24位和32位可以表示的颜色数是16777216,俗称全彩色,就是基本达到人眼可识别的极限了。以下是RGB的颜色空间图
在SimpleCG中,你也可以用SCGColor类型定义颜色,使用SCG_RGB宏或者SCG_BGR宏定义不同编码的颜色。如蓝色:
SCGColor nColor = SCG_RGB(0,0,0xFF);
颜色加亮和变暗可以使用如下函数
//加亮
SCGColor SCGAddColor( SCGColor nColor, int nAddValue );
//变暗
SCGColor SCGSubColor( SCGColor nColor, int nSubValue );
二、HSV模型
除了RGB模型使用广泛外,另外还有HSV和HSL模型也经常使用。下面先介绍HSV模型。
HSV(Hue, Saturation, Value)是指颜色的色相(Hue,简H),饱和度(Saturation,简S)和色明度(Value,简V)。
色调H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,取值范围为0°~360°。若从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°。
饱和度S:取值范围为0.0~1.0;
亮度V:取值范围为0.0(黑色)~1.0(白色)。
HSV颜色空间如下:
在SimpleCG中,HSV类型由SCGColor_HSV定义,例如定义纯红色代码如下:
SCGColor_HSV hsv = {0,1.0f,1.0f};
不过只有RGB颜色能够直接在SimpleCG绘制函数使用,所以最后要经过SCGHSV_RGB转回RGB颜色再用。
setfillcolor( SCGHSV_RGB(&hsv) );
RGB颜色也可以直接转为HSV类型,通过函数SCGRGB_HSV,例如:
COLORREF nColor = RGB(255,0,0);
SCGColor_HSV hsv = {0.0f,1.0f,1.0f};
SCGRGB_HSV(nColor,&hsv);
当使用HSV模型有什么好处呢?就是可以直接调整颜色的色相、饱和度及明度,因为这些颜色属性对人类来说更直观。
三、HSL模型
HSL模型与HSV模型非常相似,其中的H都是代表的色相,S都代表饱和度,但两者意义有一些差别。L代表Lightness,即亮度。
其中H取值范围为0°~360°。若从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。
S取值范围为0.0~1.0;数值越大越鲜明
L取值范围为0.0~1.0;0黑色,0.5颜色最鲜明,1为白色
HSL颜色模型如下
在SimpleCG中,HSL类型由SCGColor_HSL定义,例如定义纯红色代码如下:
SCGColor_HSL hsl = {0,1.0f,0.5f};
和RGB相互转换使用
//RGB ==> HSL
bool SCGRGB_HSL( SCGColor nColor, SCGColor_HSL *pHSL );
//HSL ==> RGB
COLORREF SCGHSL_RGB( SCGColor_HSL *pHSL );
四、结语
最后看看实际运用HSV的例子
// Rainbow.cpp : 定义控制台应用程序的入口点。
//
#include "../import/include/CGBoard.h"
#include "math.h"
#define C_IMAGE_WIDTH 640
#define C_IMAGE_HEIGHT 480
#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endif
void DrawProcess()
{
SCGColor_HSV hsv = {0.0f,1.0f,1.0f};
setlinewidth( 2 );
COLORREF back=0xffffff;
while(IsShowingWindow())
{
setbackcolor(back);
ClearDevice();
for(int r = 300; r > 144; r-=2)
{
hsv.fHue += 5;
if(hsv.fHue>360)
hsv.fHue -= 360;
setfillcolor( SCGHSV_RGB(&hsv) );
_solidpie(300-r,300-r,r+300,r+300,0,C_PI);
}
setfillcolor( back );
solidpie(300-144,300-144,144+300,144+300,0,C_PI);
Sleep(200);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if( !ShowingBoard(C_IMAGE_WIDTH,C_IMAGE_HEIGHT, DrawProcess))
return 1;
CloseBoard();
return 0;
}
运行效果如图
因为有HSV模型辅助,需要平滑色相过渡只需要改变H数值就可以了。如果直接用RGB恐怕很难实现,只能借助数组预设颜色了。所以运用不同颜色模型能够提高开发效率、简化逻辑。