Значения RGB цветов в индексе расширенных цветов Ansi (17-255)
Мой вопрос в целом - это сценарии оболочки с цветами ANSI, но для справки я использую Apple Mac OS X 10.9 Mavericks. Я использую приложение терминала "iTerm" в качестве терминала по умолчанию, но также проверил и встроенное приложение "терминал". Я использую ZSH (5.0.7) в качестве оболочки по умолчанию, но также проверил в BASH (3.2.51).
Я пытался выяснить, существует ли список значений RGB для 256-цветных индексированных расширенных передних / фоновых escape-кодов Ansi, доступных с помощью esc[38;5;xm и esc[48;5;xm, где x - это число от 0 до 255. Я нашел несколько сценариев, которые распечатывают цвета в виде блоков (используя индекс), но я хочу знать значения rgb каждого из цветов в индексах.
Вот пример использования ANSI-кодов:
printf '\e[38;5;222;48;5;238m Hi \e[m\n'
(\ e можно заменить на \033 или \x1b)
Так что в основном мне интересно, есть ли список или согласованные настройки для этих индексированных цветов? Например, 232-255, кажется, всегда серый градиент. Каждый найденный мной сайт, который ссылается на расширенные цвета, просто говорит о том, как его использовать, и не перечисляет никаких конкретных цветов.
Я нашел несколько ссылок на X11 и файл rgb.txt, который на первый взгляд показался мне тем, что я искал, но они, похоже, не соответствуют индексным номерам. В найденном мною файле 752 цвета (большинство дубликатов, скажем, 376, что еще больше 256). Также есть 50 оттенков серого (100, если вы считаете дубликаты), но индексированные цвета Ansi имеют 23, так что, похоже, это не то же самое. Если они каким-то образом содержат цвета в расширенном цветовом индексе ANSI, есть ли у кого-нибудь список, какие имена в каком индексе?
PS. Я знаю, что esc[38;2;r;g:bm может предположительно установить цвет, используя значения rgb, но я не могу заставить его работать на моем Mac, и меня больше интересуют значения по умолчанию для индексированных цветов.
Некоторые сайты: (можно опубликовать только 2 из-за низкой репутации? Но я проверил много сайтов)
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
страница руководства:В дополнение к стандартному цвету переднего плана и фону, urxvt может отображать до 88/256 цветов: 8 цветов ANSI плюс версии с одинаковой интенсивностью (возможно, полужирный / мерцательный), а также 72 (или 240 в режиме 256 цветов). в цветном RGB-кубе 4x4x4 (или 6x6x6) и 8 (24) цветном шкале оттенков серого.
xterm
страница руководства:Они определяют цвета для 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-терминал (3.6.2) и xfce4-терминал (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"
Эти цвета могут быть сброшены до их (настроены) по умолчанию с помощью одной из последовательностей управления
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"
Вот мои цветные утилиты. Наиболее полезными, вероятно, являются преобразователи Hex->True или RGB->256. Многое из этого я собрал благодаря вашей помощи <3
rgbtohex () {
# usage) `rgbtohex 17 0 26` ==> 1001A
# usage) `rgbtohex -h 17 0 26` ==> #1001A
addleadingzero () { awk '{if(length($0)<2){printf "0";} print $0;}';}
if [[ ${1} == "-h" ]]; then
r=${2}; g=${3}; b=${4};h='#';
else
r=${1}; g=${2}; b=${3};h='';
fi
r=`echo "obase=16; ${r}" | bc | addleadingzero`
g=`echo "obase=16; ${g}" | bc | addleadingzero`
b=`echo "obase=16; ${b}" | bc | addleadingzero`
echo "${h}${r}${g}${b}"
}
rgbto256 () {
# usage: `rgbto256 0 95, 135` ==> 22
echo "define trunc(x){auto os;os=scale;scale=0;x/=1;scale=os;return x;};" \
"16 + 36 * trunc(${1}/51) + 6 * trunc(${2}/51) +" \
" trunc(${3}/51)" | bc
# XTerm Color Number = 16 + 36 * R + 6 * G + B | 0 <= R,G,B <= 5
}
hextorgb () {
# usage) `hexttorgb "11001A" ==> 17 0 26
# usage) `hexttorgb "#11001A" ==> 17 0 26
hexinput=`echo ${1} | tr '[:lower:]' '[:upper:]'` # uppercase-ing
hexinput=`echo ${hexinput} | tr -d '#'` # remove Hash if needed
a=`echo ${hexinput} | cut -c-2`
b=`echo ${hexinput} | cut -c3-4`
c=`echo ${hexinput} | cut -c5-6`
r=`echo "ibase=16; ${a}" | bc`
g=`echo "ibase=16; ${b}" | bc`
b=`echo "ibase=16; ${c}" | bc`
echo ${r} ${g} ${b}
}
trueHexPrint () {
# Generates Truecolor Escape Sequences from Hex Strings. (remove '\\' to use)
# -fg Prints as a foreground color. (default)
# -bg Prints as a background color.
# usage) `trueHexPrint -fg "11001A" ==> '\e[38;2;17;0;26m'
# usage) `trueHexPrint -bg "11001A" ==> '\e[48;2;17;0;26m'
if [[ ${1} =~ "-fg" || ${1} =~ "-f" ]]; then
fgbg=38; hexinput=${2};
elif [[ ${1} =~ "-bg" || ${1} =~ "-b" ]]; then
fgbg=48; hexinput=${2};
else
fgbg=38; hexinput=${1}
fi
hexinput=`echo ${hexinput} | tr '[:lower:]' '[:upper:]'` # uppercase-ing
hexinput=`echo ${hexinput} | tr -d '#'` # remove Hash if needed
a=`echo ${hexinput} | cut -c-2`
b=`echo ${hexinput} | cut -c3-4`
c=`echo ${hexinput} | cut -c5-6`
r=`echo "ibase=16; ${a}" | bc`
g=`echo "ibase=16; ${b}" | bc`
b=`echo "ibase=16; ${c}" | bc`
printf "\\\\e[${fgbg};2;${r};${g};${b}m" # Remove one set of '\\' to utilize
}
XColorTable () {
i=16
for ((r = 0; r <= 255; r+=40)); do # Do Tricolor
for ((g = 0; g <= 255; g+=40)); do
for ((b = 0; b <= 255; b+=40)); do
echo "Color$((i++)) = (${r}, ${g}, ${b})"
if ((b == 0)); then b=55; fi
done
if ((b == 0)); then g=55; fi
done
if ((r == 0)); then r=55; fi
done
for ((m = 8; m <= 238; m+=10)); do # Do Monochrome
echo "Color$((i++)) = (${m}, ${m}, ${m})"
done
}
#vim: ft=sh