Значения 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 из-за низкой репутации? Но я проверил много сайтов)

У этого есть RGB для стандартных цветов, но не расширенные.

У этого есть диаграмма цветов, но не значения RGB

1 ответ

Таблица цветов 256 и ее разбиение

Цветовая гамма 256-цветного терминала состоит из 4 частей, часто 5, и в этом случае вы фактически получаете 258 цветов:

  1. Цветовые числа от 0 до 7 являются цветами терминала по умолчанию, фактическое значение RGB которых не стандартизировано и часто может быть настроено.

  2. Цвета от 8 до 15 - это "яркие" цвета. В большинстве случаев это более светлый оттенок цвета с индексом - 8. Они также не стандартизированы и часто могут быть настроены. В зависимости от терминала и оболочки они часто используются вместо или в сочетании с полужирным шрифтом.

  3. Цветовые числа от 16 до 231 являются цветами RGB. Эти 216 цветов определяются 6 значениями на каждой из трех осей RGB. То есть вместо значений 0 - 255 каждый цвет колеблется только от 0 до 5.

    Число цветов затем рассчитывается так:

    number = 16 + 36 * r + 6 * g + b
    

    с r, g а также b в диапазоне 0 - 5.

  4. Цветовые числа от 232 до 255 имеют оттенки серого с 24 оттенками серого от темного до светлого.

  5. Цвета по умолчанию для переднего плана и фона. Во многих терминалах они могут быть настроены независимо от 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
Другие вопросы по тегам