抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

简单打印

我们要打印一些特殊的字符来让终端识别,在这里需要使用ESC转义字符

先看示例:\033[1m

代码解释:

  1. 输出ESC转义字符,这是不可见字符,需要借助 ANSI 编码来获得,比如使用\033或者\u001b
  2. [字符,表示开始定义,是中括号
  3. 控制编码,如下表
  4. m字符,表示结束定义,是英文的 m 字母

常用的控制编码表(不完整):

控制编码 作用 备注
0 重置 去除所有的效果
1 加粗
2 变细 部分终端不支持
3 斜体 部分终端不支持
4 下划线
5 缓慢闪烁 每分钟 150 次以下,部分终端不支持
6 快速闪烁 每分钟 150 次以上,部分终端不支持
7 反显 将前景色与背景色交换
8 隐藏 让输出变得透明,部分终端不支持
9 删除线 部分终端不支持
21 取消粗体并添加双下划线 部分终端不支持
53 上划线 部分终端不支持

简单的 demo 代码:

// 输出加粗的字体
System.out.println("\033[1m" + "Hello, World!" + "\033[0m");

请注意使用完后一定要使用\033[0m进行还原,以免影响之后自己或其它程序的输出

让打印输出变得五彩斑斓起来

讲完了基础的使用方法,接下来就可以进入正题,如何输出彩色字体

3/4 位的简单 8 色输出

颜色在这里分为前景色和背景色两种,前景色可以就理解为字体的颜色

最简单的颜色更改代码:\033[控制编码m

最简单的 8 色输出可以用的编码:

前景色编码 背景色编码 代表颜色 前景色编码 背景色编码 代表颜色
30 40 黑色 90 100 亮黑(灰色)
31 41 红色 91 101 亮红
32 42 绿色 92 102 亮绿
33 43 黄色 93 103 亮黄
34 44 蓝色 94 104 亮蓝
35 45 品红 95 105 亮品红
36 46 青色 96 106 亮青
37 47 白色 97 107 亮白

最终呈现的颜色取决于不同的终端模拟器,即不同的终端显示的颜色会有偏差

让色彩多起来,使用 8 位的 256 色输出

8 色输出太少了,如果需要更多的颜色怎么办呢?

这就需要用到如下的代码了:

前景色更改代码:\033[38;5;颜色编码m或者\033[38;2;r;g;bm

前景色更改代码:\033[48;5;颜色编码m或者\033[48;2;r;g;bm

这里的 38、48、5 和 2 都是固定的,不可以变,我们需要的只是填充颜色编码或者 rgb 的值

对应的颜色编码这里有一个图

颜色编码取值是 0-255 这个范围

  • 0-7 对应控制编码中的标准 8 色,8-15 对应控制编码中的亮 8 色
    • 直接使用对应的控制编码会更加方便
  • 16-231 对应相应的 rgb 值,并且 0 <= r, g, b <= 5
  • 232-255 对应从黑到白的 24 阶灰度色

我们来一点示例代码:

// 输出颜色编码为22的前景色
System.out.println("\033[38;5;22m" + "Hello, World!" + "\033[0m");

// 你当然还可以组合使用
// 输出加粗的,颜色编码为22的前景色

// 组合使用
System.out.println("\033[1;38;5;22m" + "Hello, World!" + "\033[0m");
// 分开使用,推荐
System.out.println("\033[1m" + "\033[38;5;22m" + "Hello, World!" + "\033[0m");

五彩缤纷,使用 24 位颜色

随着 16 位到 24 位颜色的“真彩色”显卡的普及,很多终端都支持了 24 位的颜色

还是使用如下代码:

前景色更改代码:\033[38;2;r;g;bm

前景色更改代码:\033[48;2;r;g;bm

只是这里的 r,g,b 没有像 8 位颜色那样的 0-5 的范围限制了,你可以寻找任意的 RGB 颜色值进行填充!

第三方库

如果不想记忆这些编码,可以使用定义好这些颜色的第三方库,如 JColor

GitHub:https://github.com/dialex/JColor

maven 仓库:https://mvnrepository.com/artifact/com.diogonunes/JColor

使用例子(来自其 GitHub README.md):

// 使用情况1: 使用 Ansi.colorize() 方法在内联中格式化
System.out.println(colorize("这段是品红背景下的黄色文字", YELLOW_TEXT(), MAGENTA_BACK()));
System.out.println("\n");

// 使用情况2: 创建 Attributes 数组去定义格式化样式
Attribute[] myFormat = new Attribute[]{RED_TEXT(), YELLOW_BACK(), BOLD()};
System.out.println(colorize("这段是黄色背景下的红色加粗文字", myFormat));
System.out.println("\n");

// 使用情况3: AnsiFormat 是 Attributes 数组的语法糖
AnsiFormat fWarning = new AnsiFormat(GREEN_TEXT(), BLUE_BACK(), BOLD());
System.out.println(colorize("AnsiFormat 是声明格式化的一种很优雅的方式", fWarning));
System.out.println(fWarning.format("使用这种方式就不需要直接调用 colorize() 方法"));
System.out.println("\n");

// 使用情况4: 也支持亮色
AnsiFormat fNormal = new AnsiFormat(MAGENTA_BACK(), YELLOW_TEXT());
AnsiFormat fBright = new AnsiFormat(BRIGHT_MAGENTA_BACK(), BRIGHT_YELLOW_TEXT());
System.out.println(fNormal.format("你可以使用普通的颜色") + fBright.format("以及亮色版本"));

// 使用情况5: 使用8位颜色
System.out.println("支持任何你终端支持的 8-bit 颜色");
for (int i = 0; i <= 255; i++) {
Attribute txtColor = TEXT_COLOR(i);
System.out.print(colorize(String.format("%4d", i), txtColor));
}
System.out.println("\n");

// 使用情况6: 使用RGB
System.out.println("支持任何你终端支持的 RGB 颜色");
for (int i = 0; i <= 300; i++) {
Attribute bkgColor = BACK_COLOR(new Random().nextInt(255), new Random().nextInt(255), new Random().nextInt(255));
System.out.print(colorize(" ", bkgColor));
}
System.out.println("\n");

// 版权信息
System.out.print("This example used JColor 5.0.0 ");
System.out.print(colorize("\tMADE ", BOLD(), BRIGHT_YELLOW_TEXT(), GREEN_BACK()));
System.out.println(colorize("IN PORTUGAL\t", BOLD(), BRIGHT_YELLOW_TEXT(), RED_BACK()));
System.out.println("I hope you find it useful ;)");

评论