【问题标题】:RGB values of the colors in the Ansi extended colors index (17-255)Ansi 扩展颜色索引 (17-255) 中颜色的 RGB 值
【发布时间】:2015-01-25 09:09:10
【问题描述】:

我的问题一般是带有 ansi 颜色的 shell 脚本,但作为参考,我使用的是 Apple Mac OS X 10.9 Mavericks。我使用“iTerm”终端应用程序作为我的默认终端,但也使用内置的“终端”应用程序进行检查。我使用 ZSH (5.0.7) 作为我的默认 shell,但也检查了 BASH (3.2.51)。

我一直在尝试找出是否存在 256 色索引扩展前/背景 Ansi 转义码的 RGB 值列表,这些转义码可使用 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 上工作,我对索引颜色的默认值更感兴趣。

一些网站:(因为rep低只能发2个?但是我查了很多网站)

This one has the rgb for the standard colors but not the extended ones.

This one has a chart of the colors but not the rgb values

【问题讨论】:

  • 默认终端颜色是终端特定的。有一般的方案,但我不认为这是一个“规范”或任何东西。如果你有第二个链接中的图像,你可以很容易地从中获得他们使用的颜色的 RGB 值。
  • 顺便说一句,您可以在 OSX 上的 Applications/Utilities 文件夹中使用 Digital Color Meter 在任何应用程序(包括终端)中采样颜色。
  • 感谢您的信息,但我已经知道如何对颜色进行采样以获得 RGB。我更关心是否有一些特定的标准值。请参阅我搜索了一个标准,但没有找到一个。我不想假设如果我找不到一个,那么一个就一定不存在。所以这就是我问的原因。换句话说,我不确定我链接的图表中的那些或终端中的那些是“官方的”,还是只是开发人员决定使用的那些。

标签: bash shell terminal zsh ansi-colors


【解决方案1】:

256色表及其分区

256 色终端的颜色范围由 4 部分组成,通常是 5 部分,在这种情况下,您实际上得到了 258 种颜色:

  1. 颜色编号 0 到 7 是默认的终端颜色,其实际 RGB 值没有标准化,通常可以配置。

  2. 颜色编号 8 到 15 是“明亮”颜色。大多数情况下,这些颜色较浅,指数为 - 8。它们也不是标准化的,通常可以配置。根据终端和外壳,它们通常用于代替粗体字体或与粗体字体结合使用。

  3. 颜色编号 16 到 231 是 RGB 颜色。这 216 种颜色由三个 RGB 轴上的每个轴上的 6 个值定义。也就是说,每种颜色的范围不是 0 - 255,而是 0 - 5。

    然后这样计算颜色编号:

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

    rgb 在 0 - 5 范围内。

  4. 色号 232 到 255 为灰度,由深到亮 24 级灰度。

  5. 前景和背景的默认颜色。在许多终端中,它们可以独立于 256 种索引颜色进行配置,从而提供额外的两种可配置颜色。当不设置任何其他颜色或禁用其他颜色(即print '\e[m')时,您会得到它们。

一些来源:

  • urxvt 手册页:

    除了默认的前景色和背景色外,urxvt 最多可以显示 88/256 种颜色:8 种 ANSI 颜色加上相同的高强度(可能为粗体/闪烁)版本,以及 72 种(或 240 在 256 色模式下) ) 颜色以 4x4x4(或 6x6x6)颜色 RGB 立方体加上 8 (24) 色灰度渐变排列。

  • xterm 手册页:

    这些指定 256 色扩展的颜色。默认资源值用于颜色 16 到 231 以制作 6x6x6 颜色立方体,颜色 232 到 255 以制作灰度渐变。

  • Wikipedia article on ANSI escape codes(其本身又缺乏对该主题的引用)


默认 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 值

在某些终端(至少 xtermgnome-terminaltermiteurxvt)中,所有这些颜色都可以在运行时通过发送以下 XTerm Control Sequences 之一来更改:

OSC 4; c ; spec BEL
OSC 4; c ; spec ST

地点:

  • OSC 是转义字符(\e\033)后跟 ]
  • c 是颜色编号 (0 - 255)
  • spec 是一种颜色规范(例如,red#ff0000rgb:ff/00/00rgbi: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 BELOSC 11 ; spec BEL。例如:

echo -en "\e]10;red\a"
echo -en "\e]11;green\a"

可以分别使用OSC 110 BELOSC 111 BEL 重置:

echo -en "\e]110\a"
echo -en "\e]111\a"

【讨论】:

  • 非常好!但是您能否为您最初的 4 点定义提供一个来源? (我想了解更多)。
  • 一个内容丰富、经过充分研究和提出的答案。干得好!
  • @shellter 第一部分中的大部分信息只是积累的知识,所以我无法真正指出它的来源。我试图查找它,并且很难找到该信息的良好来源(或者我的 Google-foo 不够好)。我添加了一些我发现的内容,但说实话我自己对结果并不满意。
  • 好信息,谢谢。我在想也许没有真正的标准,但我还是会继续寻找。
  • 最新的编辑谈到了 258 种颜色,但没有澄清这一点,而且整体讨论缺乏关于何时采用这些功能以及为什么采用这些功能的任何意义。我觉得没用。
【解决方案2】:

这是我的颜色工具。最有用的可能是 Hex->True 或 RGB->256 转换器。感谢大家的帮助,我整理了很多内容

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

【讨论】:

    猜你喜欢
    • 2014-03-25
    • 2011-11-29
    • 2013-03-18
    • 2022-12-19
    • 2013-04-10
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多