C语言:通过RGB色彩模式实现字体变色效果

一、前言:

        学习C语言过程中黑屏白字难免枯燥无味,想做一些文字视图色彩变化以增加学习乐趣,故翻阅文章博客,归纳并总结,实现字体变色效果。


二、关于ANSI 转义码:

1.ANSI 转义码

        引wiki关于ANSI escape code的描述:“某些字节序列(大多数以ASCII 转义字符和括号字符开头)嵌入到文本中。终端将这些序列解释为命令,而不是逐字显示的文本。”

ANSI escape sequences are a standard for in-band signaling to control cursor location, color, font styling, and other options on video text terminals and terminal emulators. Certain sequences of bytes, most starting with an ASCII escape character and a bracket character, are embedded into text. The terminal interprets these sequences as commands, rather than text to display verbatim.”

2.常用ANSI 转义字符

Popular C0 control codes (not an exhaustive list)
^C0AbbrNameEffect
^G0x07BELBellMakes an audible noise.
^H0x08BSBackspaceMoves the cursor left (but may "backwards wrap" if cursor is at start of line).
^I0x09HTTabMoves the cursor right to next multiple of 8.
^J0x0ALFLine FeedMoves to next line, scrolls the display up if at bottom of the screen. Usually does not move horizontally, though programs should not rely on this.
^L0x0CFFForm FeedMove a printer to top of next page. Usually does not move horizontally, though programs should not rely on this. Effect on video terminals varies.
^M0x0DCRCarriage ReturnMoves the cursor to column zero.
^[0x1BESCEscapeStarts all the escape sequences

        以上为wiki中所列举的常用转义字符,C语言中使用“\xdd”(其中“dd”为两个十六进制数字)也可以实现上述转义功能;为方便使用,如下总结了C语言中较为简洁的转义字符:

转义字符释义
\a警告字符,凤鸣
\b退格符
\f进纸符
\n换行
\r回车
\t水平制表符
\v垂直制表符
\?
在书写连续多个问号时使用,防止他们被解析成三字母词
\'
用于表示字符常量 '
\"
用于表示一个字符串内部的双引号
\\
用于表示一个反斜杠,防止它被解释为一个转义序列符
\ddd
ddd 表示 1~3 个八进制的数字
\xdd
dd 表示 2 个十六进制的数字

3.关于ESC控制码

        为在C语言终端中通过RGB色彩模式实现字体变色效果,我们需要用到表一中最后一列ESC控制码,即在C语言中使用“\x1B”(或八进制“\033”)进行转义。值得注意的是,该控制码能够实现的功能不止改变字体前景色,其他转义功能参考另外一篇博客:ESC控制码

1)3位或4位色彩

        最初的规格只有8种颜色,并且只给了它们名称,即使后来增加到了16种颜色,但在此种情况下能达到的色度非常有限,不过仅做一般的色彩区分也算是够用。以下列出使用方法与色彩编号:

"\x1B[<BGcode>;<FGcode>m<str>"//引用十六进制转义字符
"\033[<BGcode>;<FGcode>m<str>"//引用八进制转义字符
//注:使用时略去<>;字符串前紧跟字符'm';BGcode与FGcode无顺序

        例如想要打印亮青色(Birght Byan)作为背景色,品红色(Megenta)作为前景色的"Hello world":

#include <stdio.h>
int main()
{
	printf("\033[106;35mHello world\033[0m");//末尾处的"\033[0m"用于重置色彩
	return 0;
}

        或者只想打印前景色或者背景色:

#include <stdio.h>
int main()
{
	printf("\033[106mHello world\033[0m");//只打印背景色
	printf("\033[35mHello world\033[0m");//只打印前景色
	return 0;
}

2)8位色彩

        介于最初4位色彩与现在24位色彩之间,若只是用于做简单的区分,上文的色度已经够用,若想要更丰富的色彩变化,8位色彩肯定是不如24位色彩,因此本文不做过多分析。这里留出wiki链接:8位色彩

3)24位色彩

        随着 16 至 24 位颜色的“真彩色”显卡变得普遍,应用程序开始支持 24 位颜色,而在C语言开发中,24位色彩的出现也意味着我们可以拥有更加真实的色彩选择,通过RGB色彩编号准确的索引到我们需要的色彩,也是本文重点研究的对象。以下列出使用方法:

"\033[38;2;<Rcode>;<Gcode>;<Bcode>m<str>"//只打印前景色
"\033[48;2;<Rcode>;<Gcode>;<Bcode>m<str>"//只打印背景色
"\033[38;2;<Rcode>;<Gcode>;<Bcode>;48;2;<Rcode>;<Gcode>;<Bcode>m<str>"//打印前景色和背景色
//注:使用时略去<>;字符串前紧跟字符'm';前景色与背景色无顺序、RGBcode有顺序;
//"38"或"48"后的"2"不可省略

        例如想打印前景色为(255,162,170)背景色为(0,120,127)的字符串"YubiSaki":

#include <stdio.h>
int main()
{
	printf("\033[38;2;255;162;170;48;2;0;120;127mYubiSaki\033[0m");
	return 0;
}

三、实现字体变色

1.关于RGB色彩变化

        有关RGB的色彩知识还是比较深的,这里只做简单的描述。例如我们想在最纯的(饱和度与明度最高)Red、Green、Blue中循环变色,基本规律是此消彼长:

Red(255,0,0) → (255,255,0) → Green(0,255,0) → (0,255,255) → Blue(0,0,255) → (255,0,255) → Red(255,0,0)

2.函数实现

#include <stdio.h>
#include <Windows.h>
int main()
{
//初始化RGB数值
	int r = 255;
	int g = 0;
	int b = 0;
	while (1)
	{
		for (int i = 0; i < 255; i++)
		{
			Sleep(1);//延迟变色
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);//打印
			printf("\r");//清除行
			g++;
		}
		for (int i = 1; i < 255; i++)
		{
			Sleep(1);
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);
			printf("\r");
			r--;
		}
		for (int i = 1; i < 255; i++)
		{
			Sleep(1);
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);
			printf("\r");
			b++;
		}
		for (int i = 1; i < 255; i++)
		{
			Sleep(1);
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);
			printf("\r");
			g--;
		}
		for (int i = 0; i < 255; i++)
		{
			Sleep(1);
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);
			printf("\r");
			r++;
		}
		for (int i = 1; i < 255; i++)
		{
			Sleep(1);
			printf("\033[38;2;%d;%d;%dmYubiSaki\033[0m", r, g, b);
			printf("\r");
			b--;
		}
	}
	return 0;
}

  • 29
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值