EGE专栏:EGE专栏
文章目录
学习准备
经过前面的学习,相信大家已经了解关于绘图的颜色,坐标系等知识,并且学会了如何使用EGE 创建窗口。那么接下来就开始用EGE画图吧!当然,色彩是不可缺少的,在画图之前,先来看看EGE如何设置颜色。
一、EGE中的三种颜色
更详细的内容请参考 EGE基础:颜色篇
在EGE中,颜色主要分为三类:前景色,背景色和填充色。
颜色类型 |
|
---|---|
前景色 | 指文字,线条,图形边框的颜色 |
背景色 | 指窗口或视口区域的底色 |
填充色 | 指封闭图形内部区域的颜色 |
二、EGE中的颜色表示
1. color_t 颜色类型
在EGE中,颜色的类型为 color_t,实际上是个4字节大小的整数类型,正好用4个字节来表示ARGB颜色。
color_t color = EGERGB(0xFF, 0x00, 0x00); //纯红色
2. EGERGB宏 与 EGEARGB宏
EGE中,常用 EGERGB 宏表示 RGB颜色,EGEARGB宏 表示ARGB颜色,例如:
EGERGB(0xCC, 0x80, 0xAA) //对应RGB颜色 #CC80AA
EGEARGB(0xFF, 0xCC, 0x80, 0xAA) //对应ARGB颜色 #FFCC80AA
3. ARGB颜色
ARGB颜色相比RGB颜色多了个透明度(Alpha),用于表示和原有颜色做颜色混合时所占的比例,0~255 分别对应0.0 ~ 1.0。
最终颜色都是以RGB颜色来表示的。最终颜色是由混合的两种颜色共同决定,也就是说,背景颜色的不同会使得混合后的最终颜色值不同。
ARGB颜色混合计算公式
两个带alpha通道的ARGB颜色混合,一般使用的颜色混合公式是(alpha范围为0.0~1.0):
R
G
B
最终颜色
=
(
1.0
−
a
l
p
h
a
)
⋅
R
G
B
原颜色
+
a
l
p
h
a
⋅
R
G
B
当前颜色
\mathrm{RGB_{最终颜色} = (1.0- alpha) \cdot RGB_{原颜色} +alpha \cdot RGB_{当前颜色}}
RGB最终颜色=(1.0−alpha)⋅RGB原颜色+alpha⋅RGB当前颜色
此公式只使用当前颜色的alpha值参与两个颜色混合的比例计算,不考虑原颜色的alpha值。
4. 其它颜色表示方法
颜色也可以直接用32位的整数表示,一般写成十六进制,如 0x80338855
,表示颜色 EGEARGB(0x80, 0x33, 0x88, 0x55)
,但需要注意,EGE 实际是使用ARGB颜色,而RGB颜色对应的实际是Alpha值为0xFF的ARGB颜色,所以RGB颜色值 0xCC80AA 应该对应ARGB颜色值 0xFFCC80AA。
还有EGEACOLOR,用来组合 Alpha值 和 RGB颜色 ,合成新的ARGB颜色。因为EGEACOLOR中的alpha参数已经给出了最终颜色的Alpha值,所以颜色参数中的alpha值会被舍弃,可以省略不写。
color_t ArgbColor = EGEACOLOR(0xFF, RgbColor);
例如:
EGEACOLOR(0xFF, BLUE)
上面那个BLUE是什么呢? 是EGE为了方便表示颜色,而定义的一些枚举值,这样就可以简单的单词来代替颜色,不需要实际记忆具体的颜色RGB数值。
那到底EGE已经定义了哪些颜色枚举呢?
EGE定义的颜色枚举名为COLORS,可以在 ege.h 头文件中查看相关定义。
enum COLORS {...}
常用的颜色定义如 WHITE(白), BLACK(黑),RED(红), GREEN(绿) 等,其它可以自行在 ege.h 头文件中查找,要学会自行查看头文件,毕竟声明都包含在头文件中。当然,也可以直接查看更详细的 EGE基础:颜色篇
5. EGE中RGB颜色的版本改动
EGE19.01版本之前 EGERGB宏定义的数值为 0x00RRGGBB,EGE20.08版本之后改为 0xFFRRGGBB,
EGE20.08版本后将RGB颜色的 透明度由0x00改为0xFF,这个改动是为了更符合定义。否则对于设置的RGB颜色,对应的ARGB颜色透明度为0,相当于全透明,如果函数绘图时通过透明度混合颜色,那么图形将完全不可见。
影响的主要是一些会计算颜色透明度的函数,如EGE中的高级绘图函数,透明贴图 putimage_withalpha() 等,而那些忽略透明度,只取颜色中的RGB数值的函数则不受影响。
三、EGE画笔颜色设置
颜色 | 设置函数 | 涉及的图形颜色 |
---|---|---|
前景色 | setcolor() | 线条,文字、图形边框的颜色。 |
背景色 | setbkcolor(), setbkcolor_f() | 窗口或视口区域的底色 |
填充色 | setfillcolor() | 封闭图形内部的填充颜色 |
文字背景色 | setfontbkcolor() | 文字背景色 |
当然,这几个函数仅仅只是用来设置相应画笔的颜色,只有真正调用绘图函数来绘图,才能看到由这几支 “画笔” 共同绘制出的图形。
即,颜色设置仅影响后面绘制出的图形的颜色,而之前已经绘制出的图形,其颜色不会改变。
其中特殊的便是背景色设置setbkcolor(),设置后原背景色会替换为新背景色,原因便是调用后,会有只 “画笔” 将图中原来的背景色都描成新背景色。
那如果觉得这支笔太主动了,并不想让它帮我们替换颜色呢?那可以使用 setbkcolor_f() ,它仅仅只设置背景色,并不会实际去改变原图中像素的颜色,配置 cleardevice()清屏时使用。
下面就是实际的设置颜色了
setbkcolor(WHITE); //设置背景色
setcolor(EGERGB(0x30, 0x80, 0xFF); //设置前景色
setfillcolor(EGEARGB(0x80, 0xB0, 0xB0, 0x20)); //设置填充颜色
问题1:
为什么调用 setcolor(), setfillcolor() 后,之前图形的前景色和填充颜色并没有变化?
setcolor(), setfillcolor() 仅仅只是设置 画笔的颜色,也就是换上其它颜色的画笔,只是换支画笔而已,所以并不影响已经画上去的图形。
问题2:
如果说设置颜色只是改变画笔颜色,那为什么调用 setbkcolor() 后,图形背景色变化了呢?
这个在于 setbkcolor() 的特殊性,setbkcolor() 不仅仅是设置画笔颜色,还会将窗口上等于原背景颜色的像素修改为新背景色。所以仅设置画笔颜色的改变背景颜色函数应该是 setbkcolor_f()
问题3:
这三个颜色什么时候设置呢?换句话说 setcolor(), setfillcolor(),setbkcolor() 应该在什么时候调用?
背景色应该在进行绘图之前设置好,并确保背景色已经应用到图中,而不是仅仅设置"画笔"。
setcolor() 和 setfillcolor() 根据需要,在每个图形绘制之前设置好对应的画笔颜色,如果这些图形的填充色和前景色都是一样的,那么在一开始设置一次就可以了。
问题4:
如果要绘制的几个图形的填充色,前景色都不同,那怎么办呢?
那就要需要每次绘制图形前,把画笔颜色调整好,即调用 setcolor() 和 setfillcolor() 分别将前景色和填充色设置成对应的颜色,再进行绘制,这样绘制出的图形就能得到想要的颜色啦!
四、挑选自己喜欢的颜色
1. 对颜色不了解,怎么找好看的颜色呢
首先,可以在网上搜索 颜色表,配色 等关键词,这样就可以找到很多别人挑选好的好看的颜色,相信你会有很大的收获的。
例如:下面是找的几个配色网站
颜色对照表
配色表
New Flat UI Color Picker
coolors
Material UI Colors
下面是其中两个网站的界面截图
coolors
Material UI Colors
2. 这是啥颜色?
看到喜欢的颜色,却不知道颜色参数怎么办?
这就需要用吸管工具来提取颜色啦!
2.1 自带画图工具
先截个图,如果本来就是张图片的话,那就不需要截图了。然后用 画图 打开这张图,按如下步骤,先点击吸管工具,然后点击图片上某个颜色,最后点击编辑颜色按钮,就会弹出颜色编辑框。
这时就能看到颜色对应的RGB值了。
2.2 Snipaste
Snipaste是个好用的截图贴图工具,截图时自带放大镜,显示屏幕上像素点的颜色。
在Snipaste中,可以看到左上角有个放大镜,显示像素点的屏幕坐标和RGB颜色值,按C即可复制颜色值,并且可以设置十进制或十六进制显示,方便快捷。
五、来点色图!
给你们看看色图!
色图示例
来看看实际的例子,画了十份色图。
主要使用的绘图函数是 bar(), 用于绘制填充矩形,使用RGB颜色,忽略透明度。
可以看到,图像中的马赫带效应很明显,色带边缘处由于明暗差异大而造成人眼识别颜色有偏差,而实际同一个色块内的颜色都是相同的,可以通过遮挡其它色块来验证。
完整代码:
#include <graphics.h>
int main()
{
int gridWidth = 64, gridNum = 10;
int width = gridWidth * gridNum;
int height = 240;
initgraph(width, height, INIT_RENDERMANUAL); //初始化窗口
setbkcolor(WHITE); //设置窗口背景色为白色
//这些是直接复制过来RGB颜色值
color_t rgbColors[10] = {
0x7400b8, 0x6930c3, 0x5e60ce, 0x5390d9, 0x4ea8de,
0x48bfe3, 0x56cfe1, 0x64dfdf, 0x72efdd, 0x80ffdb,
};
//画10个填充矩形,每个填充矩形的颜色定义在RgbColors数组中
for (int i = 0; i < gridNum; i++)
{
//设置对应的填充颜色(这里转成将上面的 RGB 颜色转成 ARGB 颜色))
setfillcolor(EGEACOLOR(0xFF, rgbColors[i]));
//画个填充矩形
bar(i * gridWidth, 0, (i + 1) * gridWidth, height);
}
getch();
closegraph();
return 0;
}
更详细的内容请参考 EGE基础:颜色篇
EGE专栏:EGE专栏