Ответ 1
Таблица цветов 256 и ее разбиение
Цветовой диапазон 256-цветного терминала состоит из 4 частей, часто 5, и в этом случае вы получаете 258 цветов:
-
Номера цветов от 0 до 7 являются цветами терминала по умолчанию, фактическое значение RGB которого не стандартизировано и часто может быть настроено.
-
Номера цветов с 8 по 15 являются "яркими" цветами. В большинстве случаев это более светлый оттенок цвета с индексом - 8. Они также не стандартизированы и часто могут быть настроены. В зависимости от терминала и оболочки они часто используются вместо или в сочетании с полужирным шрифтом.
-
Номера цветов от 16 до 231 являются цветами RGB. Эти 216 цветов определяются 6 значениями на каждой из трех осей RGB. То есть вместо значений 0 - 255 каждый цвет будет только от 0 до 5.
Затем число цветов рассчитывается следующим образом:
number = 16 + 36 * r + 6 * g + b
с
r
,g
иb
в диапазоне 0-5. -
Номера цветов от 232 до 255 имеют оттенки серого с 24 оттенками серого от темного до светлого.
-
Стандартные цвета для переднего плана и фона. Во многих терминалах они могут быть настроены независимо от 256 индексированных цветов, что дает дополнительные два настраиваемых цвета. Вы получаете их, когда не устанавливаете какой-либо другой цвет или не отключите другие цвета (т.е.
print '\e[m'
).
Некоторые источники:
-
urxvt
manpage:В дополнение к цветам переднего плана и фона по умолчанию urxvt может отображать до 88/256 цветов: 8 цветов ANSI плюс высокоинтенсивные (потенциально жирные/мигающие) версии одного и того же цвета и 72 (или 240 цветов в 256 цветовых режимах ) цвета, размещенные в купе RGB 4x4x4 (или 6x6x6) плюс 8 (24) цветовая шкала оттенков серого.
-
xterm
manpage:Они определяют цвета для 256-цветного расширения. Значения ресурсов по умолчанию предназначены для цветов с 16 по 231, чтобы сделать куб цвета 6x6x6 и цвета от 232 до 255, чтобы сделать рамку шкалы серого.
-
Статья в Википедии об экранирующих кодах ANSI (которая, в свою очередь, отсутствует в цитате по теме)
Значения по умолчанию RGB
Теоретически, чтобы получить одинаково распределенный диапазон цветов, значения RGB для цветов в диапазоне 16-231 могут быть рассчитаны следующим образом:
# 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]
для красного, зеленого и синего значений [0, 95, 135, 175, 215, 255]
по осям цвета RGB. (Я тестировал с 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
256colres.pl
в корне Источники XTerm (версия 313) использует аналогичный алгоритм для генерации 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);
}
Отображение доступных цветов в терминале
Вот функция zsh, которая печатает все цвета на 256-цветном терминале (если для параметра 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:
OSC 4; c ; spec BEL
OSC 4; c ; spec ST
где:
-
OSC
- это escape-символ (\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"
Эти цвета могут быть reset для их (настроенных) по умолчанию с одной из управляющих последовательностей
OSC 104 ; c BEL
OSC 104 ; c ST
Итак, следующий цикл будет reset для всех цветов от 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"
Это могут быть reset с OSC 110 BEL
и OSC 111 BEL
соответственно:
echo -en "\e]110\a"
echo -en "\e]111\a"