Подтвердить что ты не робот

Значения RGB цветов в индексе расширенных цветов Ansi (17-255)

Мой вопрос в общем shell-скриптинг с ansi-цветами, но для справки Я использую Apple Mac OS X 10.9 Mavericks. Я использую терминальное приложение "iTerm" в качестве терминала по умолчанию, но также проверено со встроенным "терминальным" приложением. Я использую ZSH (5.0.7) в качестве моей оболочки по умолчанию, но также отмечен в BASH (3.2.51).

Я пытаюсь выяснить, есть ли список значений RGB для 256 цветных индексированных расширенных fore/background-кодов Ansi escape, которые доступны с помощью esc [38; 5; xm и esc [48; 5; xm где x - число от 0 до 255. Я нашел несколько сценариев, которые печатают цвета как блоки (используя индекс), но я хочу знать значения rgb каждого из цветов в индексах.

Вот пример используемых анси-кодов:

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

4b9b3361

Ответ 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"

Ответ 2

Вот мои цветные утилиты. Наиболее полезными, вероятно, являются конвертеры 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