45

我知道在 bash 终端中更改颜色的可靠方法是使用 ANSI 转义序列。例如:

echo -e "\033[0;31mbrown text\033[0;00m"

应该输出

brown text (in brown)

有没有办法使用带有 ANSI 的特定 RGB 集输出颜色?说我想要鲜红色:

echo -e "**\033[255:0:0m**red text\033[0;00m"

这种事情存在吗?

我只想使用标准 bash。

4

6 回答 6

89

这里的两个答案都没有提到Truecolor ANSI对 8bpc 颜色的支持。这将获得 OP 最初要求的 RGB 颜色。

在以下三个控制段中;5,使用;2并指定RGB值 (0-255)代替。

\x1b[38;2;40;177;249m

要测试您的终端是否支持 Truecolor

printf "\x1b[38;2;40;177;249mTRUECOLOR\x1b[0m\n"

在我的机器上,XTerm 愉快地输出了正确的颜色;虽然,以现代 RGB 颜色之前的终端为模型的终端通常不支持真彩色 - 在使用转义码的这个特定变体之前,请确保您知道您的目标。


我还想指出38;5/ ;2- Blue Ice提到38路线然后5改变颜色。这有点不正确。

38是 xterm-256 扩展前景色代码;30-只是所有 vt100/xterm 兼容的彩色终端都支持的 16 色前景代码(在某些系统上37亮度由转义代码控制,并且可以说是支持的非标准“明亮”代码)。19097

;2和指示颜色的;5格式,最终告诉终端要提取多少序列:;5指定仅需要 1 个控制段的 8 位格式(如 Blue Ice 所述),并;2指定需要 3 个完整的 24 位 RGB 格式控制段。

这些扩展模式在技术上是“未记录的”并且是完全实现定义的。据我所知并可以研究,它们不受ANSI 委员会的管辖。


对于这种倾向,5;(256 色)格式以 16 种原始颜色(深色/浅色,因此 30-37 和 90-97)作为颜色 0-15 开始。

前面的 216 种颜色 (16-231) 由偏移 16 的 3bpc RGB 值形成,打包成一个值。

最后的 24 种颜色 (232-256) 是灰度的,从比黑色稍浅的阴影开始,一直到比白色稍暗的阴影。一些模拟器将这些步骤解释为所有三个通道上 ( ) 的线性增量256 / 24,尽管我遇到了一些似乎明确定义这些值的模拟器。

这是一个执行这种转换的 Javascript 函数,它考虑了所有的灰色。

function rgbToAnsi256(r, g, b) {
    // we use the extended greyscale palette here, with the exception of
    // black and white. normal palette only has 4 greyscale shades.
    if (r === g && g === b) {
        if (r < 8) {
            return 16;
        }

        if (r > 248) {
            return 231;
        }

        return Math.round(((r - 8) / 247) * 24) + 232;
    }

    var ansi = 16
        + (36 * Math.round(r / 255 * 5))
        + (6 * Math.round(g / 255 * 5))
        + Math.round(b / 255 * 5);

    return ansi;
}

因此,在某种程度上,您可以通过将初始 RGB 值从 8 位减少到 3 位来计算256 种 ANSI 颜色,以便在您想在不支持 Truecolor 的终端上以编程方式执行此操作时形成 256 编码值。

于 2014-10-31T01:06:45.557 回答
52

这确实存在,但不是 OP 正在寻找的 16777216 (256^3) 种颜色,而是在更大的 256 种颜色集中有 216 种 (6^3) 种均匀分布的颜色。例子:

echo -e "\033[38;5;208mpeach\033[0;00m"

这将输出一种令人愉悦的桃色文本。


拆开这个命令:\033[38;5;208m

\033是转义码。[ 38; 将命令引导到前台。如果您想更改背景颜色,请使用[48; 反而。5 ; 只是改变颜色的序列的一部分。最重要的部分208m选择实际颜色。


在此转义的 256 色序列中可以找到 3 组颜色。第一组是基本的“糖果”颜色组,或值 0-15。然后是一个分布颜色的立方体,从 16 到 231。最后有一个从 232 到 255 的详细灰度集。

您可以在此处找到包含所有这些值的表格:http: //bitmote.com/index.php?post/2012/11/19/ Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt- on-Linux#256%20(8-bit)%20Colors

于 2013-03-29T23:02:15.003 回答
4

这将起作用

echo -e "**\033[38;2;255;0;0m**red text\033[0;00m"

格式:"\033[38;2;R;G;Bm"

  • R 是 RGB 的 RED 分量
  • G 是 RGB 的绿色分量
  • B 是 RGB 的蓝色分量
于 2020-07-08T06:27:11.280 回答
2

当前,某些终端仿真器支持真彩色转义序列 (\e[38;2;R;G;Bm),包括 gnome-terminal (vte >= 0.36)、konsole 和 st [suckless]。

某些其他功能支持该功能,例如 pterm [putty]、terminology [enlightenment]、urxvt。

xterm 介于两者之间:它识别转义序列,但将每种颜色四舍五入到 256 色调色板中最接近的一种。

于 2015-04-16T23:36:14.260 回答
0

不,没有。

对于 nitpick,这些在技术上不是“ANSI 转义序列”,而是VT100 控制代码(早在出现图形终端和“RGB”等术语之前就已定义)。

于 2013-03-28T13:08:35.273 回答
0

中使用 RGB(和 HSV)

终端中的 ANSI 序列。

在 bash 中有两种打印颜色的方法。

在使用xterm 的源代码树上找到的好工具后,以下是vttests/256colors2.pl我的gnome-terminal上的显示方式:

vttests/256colors2.pl

这使用 ANSI 语法\e[48;5;COLORm

printf '\e[48;5;%sm' $color;

而不是\e[48;2;RED;GREEN;BLUEm

printf '\e[48;2;%s;%s;%sm' $red $green $blue;

我已经完成了一些函数来使用 RGB 和 HSV:

RGB 转 HSV

hsv() {
    local -n _result=$4
    local -i _hsv_min _hsv_t
    local _hsv_s
    local -i _hsv_max=" $1 > $2 ?
                (_hsv_min=($2 > $3 ? $3:$2 ), ( $1 > $3 ? $1 : $3 )) :
                (_hsv_min=($1 > $3 ? $3:$1 ), $2) > $3 ? $2 : $3 "
    case $_hsv_max in 
        $_hsv_min) _hsv_t=0 ;;
        $1) _hsv_t=" ( 60 * ( $2 - $3 ) / ( _hsv_max-_hsv_min )+ 360 )%360";;
        $2) _hsv_t=" 60 * ( $3 - $1 ) / ( _hsv_max-_hsv_min )+ 120 " ;;
        $3) _hsv_t=" 60 * ( $1 - $2 ) / ( _hsv_max-_hsv_min )+ 240 " ;;
    esac
    _hsv_s=0000000$(( _hsv_max==0?0 : 100000000-100000000*_hsv_min / _hsv_max ))
    printf -v _hsv_s %.7f ${_hsv_s::-8}.${_hsv_s: -8}
    _result=($_hsv_t $_hsv_s $_hsv_max)
}

然后

RED=255 GREEN=240 BLUE=128
hsv $RED $GREEN $BLUE hsvAr
echo ${hsvAr[@]}
52 0.4980392 255
printf 'Hue: %d, Saturation: %f, Value: %d\n' "${hsvAr[@]}"
Hue: 52, Saturation: 0.498039, Value: 255

HSV 转 RGB

rgb() {
    local -n _result=$4
    local -i _rgb_i=" (($1%360)/60)%6 "
    local -i _rgb_f=" 100000000*($1%360)/60-_rgb_i*100000000 "
    local _rgb_s
    printf -v _rgb_s %.8f "$2"
    _rgb_s=$((10#${_rgb_s/.}))
    local -i _rgb_l=" $3*(100000000-_rgb_s)/100000000 "
    case $_rgb_i in
        0 )
            local -i _rgb_n="$3*(100000000-(100000000-_rgb_f)*_rgb_s/100000000)/
                                100000000 "
            _result=("$3" "$_rgb_n" "$_rgb_l") ;;
        1 )
            local -i _rgb_m=" $3*(100000000-_rgb_f*_rgb_s/100000000)/100000000 "
            _result=("$_rgb_m" "$3" "$_rgb_l") ;;
        2 )
            local -i _rgb_n="$3*(100000000-(100000000-_rgb_f)*_rgb_s/100000000)/
                                100000000 "
            _result=("$_rgb_l" "$3" "$_rgb_n") ;;
        3 )
            local -i _rgb_m=" $3*(100000000-_rgb_f*_rgb_s/100000000)/100000000 "
            _result=("$_rgb_l" "$_rgb_m" "$3") ;;
        4 )
            local -i _rgb_n="$3*(100000000-(100000000-_rgb_f)*_rgb_s/100000000)/
                                100000000 "
            _result=("$_rgb_n" "$_rgb_l" "$3") ;;
        * )
            local -i _rgb_m=" $3*(100000000-_rgb_f*_rgb_s/100000000)/100000000 "
            _result=("$3" "$_rgb_l" "$_rgb_m") ;;
    esac
}

然后

rgb 160 .6 240 out
echo ${out[@]}
96 240 192
printf '\e[48;5;%d;%d;%dm    \e[0m\n' "${out[@]}"

会产生一堆彩色空间。

进一步:hsvrgb-browser.sh

前言:将前两个函数存储到一个名为 的文件中,与下载的 hsvrgb-browser.shhsvrgb.sh存储在同一目录中。

在此处输入图像描述

HSV-RGB Color browser - Usage: 

  [RrGgBbVb] Incrase/decrase value by step ('1'), from 0 to 255..
  [HhTt]     Incrase/decrase Hue (tint), loop over 0 - 359.
  [Ss]       Increase/decrase Saturation by .006 x step (1).
  [Cc]       Toggle Color bar rendering (upper C fix HSV)
  [+-]       Incrase/decrase step.
  [u]        show this.
  [q]        quit.
于 2022-01-29T12:42:19.117 回答