256色表及其分区
256 色终端的颜色范围由 4 部分组成,通常是 5 部分,在这种情况下,您实际上得到了 258 种颜色:
颜色编号 0 到 7 是默认的终端颜色,其实际 RGB 值没有标准化,通常可以配置。
颜色编号 8 到 15 是“明亮”颜色。大多数情况下,这些颜色较浅,指数为 - 8。它们也不是标准化的,通常可以配置。根据终端和外壳,它们通常用于代替粗体字体或与粗体字体结合使用。
-
颜色编号 16 到 231 是 RGB 颜色。这 216 种颜色由三个 RGB 轴上的每个轴上的 6 个值定义。也就是说,每种颜色的范围不是 0 - 255,而是 0 - 5。
然后这样计算颜色编号:
number = 16 + 36 * r + 6 * g + b
r、g 和 b 在 0 - 5 范围内。
色号 232 到 255 为灰度,由深到亮 24 级灰度。
前景和背景的默认颜色。在许多终端中,它们可以独立于 256 种索引颜色进行配置,从而提供额外的两种可配置颜色。当不设置任何其他颜色或禁用其他颜色(即print '\e[m')时,您会得到它们。
一些来源:
默认 RGB 值
理论上,为了获得均匀分布的颜色范围,16 - 231 范围内颜色的 RGB 值可以这样计算:
# example in Python: // is integer divison, % is modulo
rgb_R = ((number - 16) // 36) * 51
rgb_G = (((number - 16) % 36) // 6) * 51
rgb_B = ((number - 16) % 6) * 51
但是好像实际方法不一样:
我测试的任何终端仿真器似乎都遵循 XTerm 并将红色、绿色和蓝色的值 [0, 1, 2, 3, 4, 5] 映射到 RGB 色轴上的值 [0, 95, 135, 175, 215, 255]。 (我使用 XTerm (297) URxvt (v9.19)、ROXTerm (2.8.1)、gnome-terminal (3.6.2) 和 xfce4-terminal (0.6.3) 进行了测试)
给定索引的 RGB 值可以使用此算法计算:
# example in Python: 'a = b if c else d' is 'a = (c) ? b : d` in C, Perl, etc.
index_R = ((number - 16) // 36)
rgb_R = 55 + index_R * 40 if index_R > 0 else 0
index_G = (((number - 16) % 36) // 6)
rgb_G = 55 + index_G * 40 if index_G > 0 else 0
index_B = ((number - 16) % 6)
rgb_B = 55 + index_B * 40 if index_B > 0 else 0
灰度似乎遵循这个简单的公式:
rgb_R = rgb_G = rgb_B = (number - 232) * 10 + 8
XTerm sources (version 313)的根中的256colres.pl使用类似的算法生成256colres.h,其中包含256色模式的颜色定义:
$line1="COLOR_RES(\"%d\",";
$line2="\tscreen.Acolors[%d],";
$line3="\tDFT_COLOR(\"rgb:%2.2x/%2.2x/%2.2x\")),\n";
# colors 16-231 are a 6x6x6 color cube
for ($red = 0; $red < 6; $red++) {
for ($green = 0; $green < 6; $green++) {
for ($blue = 0; $blue < 6; $blue++) {
$code = 16 + ($red * 36) + ($green * 6) + $blue;
printf($line1, $code);
printf($line2, $code);
printf($line3,
($red ? ($red * 40 + 55) : 0),
($green ? ($green * 40 + 55) : 0),
($blue ? ($blue * 40 + 55) : 0));
}
}
}
# colors 232-255 are a grayscale ramp, intentionally leaving out
# black and white
$code=232;
for ($gray = 0; $gray < 24; $gray++) {
$level = ($gray * 10) + 8;
$code = 232 + $gray;
printf($line1, $code);
printf($line2, $code);
printf($line3,
$level, $level, $level);
}
在终端中显示可用颜色
这是一个在 256 色终端上打印所有颜色的 zsh 函数(如果 TERM 设置为 256 色值):
function termcolors ()
{
print TERM
print -P "Foreground: >█<"
print -P "Background: >%S█%s<\n"
print " 0 1 2 3 4 5 6 7"
for b (0 1)
do
printf "%d %2d " $b $(( 8 * b ))
for r (0 1 2 3 4 5 6 7)
do
c=$(( 8 * b + r ))
print -nP "%K{$c} %k"
done
printf " %2d\n" $(( 8 * b + 7 ))
done
print
print RGB
for r (0 1 2 3 4 5)
do
print "$r $(( 16 + 36 * r )) - $(( 16 + 36 * r + 35 ))\n 0 1 2 3 4 5"
for g (0 1 2 3 4 5)
do
printf "%d %3d " $g $(( 16 + 36 * r + 6 * g ))
for b (0 1 2 3 4 5)
do
c=$(( 16 + 36 * r + 6 * g + b ))
print -nP "%K{$c} %k"
done
printf " %3d\n" $(( 16 + 36 * r + 6 * g + 5))
done
print
done
print
print GRAY
for g in $(seq 0 23)
do
c=$(( 232 + g ))
printf "%2d %3d " $g $c
print -P "%K{$c} %k"
done
}
在运行时更改 RGB 值
在某些终端(至少 xterm、gnome-terminal、termite 和 urxvt)中,所有这些颜色都可以在运行时通过发送以下 XTerm Control Sequences 之一来更改:
OSC 4; c ; spec BEL
OSC 4; c ; spec ST
地点:
-
OSC 是转义字符(\e 或 \033)后跟 ]
-
c 是颜色编号 (0 - 255)
-
spec 是一种颜色规范(例如,red、#ff0000、rgb:ff/00/00、rgbi:1/0/0 - 实际效果可能取决于终端)
-
BEL 是响铃字符(\a 或 \007)
-
ST 是字符串终止符 \e\\ 或 \033\\
这些控制序列可以通过简单地用echo打印来发送:
echo -en "\e]4;COLOR;SPEC\a"
echo -en "\e]4;COLOR;SPEC\a"
例如,为了将 5 号颜色(通常是一些洋红色的阴影)设置为红色,这些都应该可以工作:
echo -en "\e]4;5;red\a"
echo -en "\e]4;5;#ff0000\e\\"
echo -en "\033]4;5;rgb:ff/00/00\007"
可以使用控制序列之一将这些颜色重置为其(配置的)默认值
OSC 104 ; c BEL
OSC 104 ; c ST
因此,以下循环会将所有颜色从 0 到 255 重置为其配置或默认值:
for c in {0..255}; do
echo -en "\e]104;$c\a"
done
对于默认的前景色和背景色,控制序列分别为OSC 10 ; spec BEL 和OSC 11 ; spec BEL。例如:
echo -en "\e]10;red\a"
echo -en "\e]11;green\a"
可以分别使用OSC 110 BEL 和OSC 111 BEL 重置:
echo -en "\e]110\a"
echo -en "\e]111\a"