ANSI Color Specific RGB Sequence Bash

早过忘川 提交于 2019-11-28 15:39:34

问题


I know that in bash terminals a reliable way to change color is using ANSI escape sequences. For example:

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

should output

brown text (in brown)

Is there a way to output color using a specific RGB set with ANSI? Say I want bright red:

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

Does this sort of thing exist?

I just want to use standard bash.


回答1:


Both answers here fail to mention the Truecolor ANSI support for 8bpc color. This will get the RGB color the OP originally asked for.

Instead of ;5, use ;2, and specify the R, G, and B values (0-255) in the following three control segments.

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

To test if your terminal supports Truecolor:

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

On my machine, XTerm happily outputted the correct color; although, terminals that are modeled after terminals that predate modern RGB color generally will not support truecolor - make sure you know your target before using this particular variant of the escape code.


I'd also like to point out the 38 and the ;5/;2 - Blue Ice mentioned that 38 routes and then 5 changes the color. That is slightly incorrect.

38 is the xterm-256 extended foreground color code; 30-37 are simply 16-color foreground codes (with a brightness controlled by escape code 1 on some systems and the arguably-supported 90-97 non-standard 'bright' codes) that are supported by all vt100/xterm-compliant colored terminals.

The ;2 and ;5 indicate the format of the color, ultimately telling the terminal how many more sequences to pull: ;5 specifying an 8-bit format (as Blue Ice mentioned) requiring only 1 more control segment, and ;2 specifying a full 24-bit RGB format requiring 3 control segments.

These extended modes are technically "undocumented" and are completely implementation defined. As far as I know and can research, they are not governed by the ANSI committee.


For the so inclined, the 5; (256 color) format starts with the 16 original colors (both dark/light, so 30-37 and 90-97) as colors 0-15.

The proceeding 216 colors (16-231) are formed by a 3bpc RGB value offset by 16, packed into a single value.

The final 24 colors (232-256) are greyscale starting from a shade slightly lighter than black ranging up to a shade slightly darker than white. Some emulators interpret these steps as linear increments from (256 / 24) on all three channels, though I've come across some emulators that seem to explicitly define these values.

Here is a Javascript function that performs such a conversion, taking into account all of the greys.

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;
}

So in a way, you can calculate 256 ANSI colors from initial RGB values by reducing them from 8 to 3 bits in order to form a 256 encoded value in the event you want to programmatically do so on terminals that do not support Truecolor.




回答2:


This does exist, but instead of the 16777216 (256^3) colors that the OP was looking for, there are 216 (6^3) equally distributed colors, in a larger set of 256 colors. Example:

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

This will output a pleasing sort of peach colored text.


Taking apart this command: \033[38;5;208m

The \033 is the escape code. The [38; directs command to the foreground. If you want to change the background color instead, use [48; instead. The 5; is just a piece of the sequence that changes color. And the most important part, 208m, selects the actual color.


There are 3 sets of colors that can be found in the 256 color sequence for this escape. The first set is the basic "candy" color set, or values 0-15. Then there is a cube of distributed colors, from 16-231. Lastly there is a detailed grayscale set from 232-255.

You can find a table with all of these values here: 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




回答3:


Currently true color escape sequences (\e[38;2;R;G;Bm) are supported by certain terminal emulators including gnome-terminal (with vte >= 0.36), konsole, and st [suckless].

The feature is not supported by certain others, e.g. pterm [putty], terminology [enlightenment], urxvt.

xterm is halfway in between: it recognizes the escape sequences, but rounds every color to the nearest one in the 256-color palette.




回答4:


No there's not.

And to nitpick, those are technically not "ANSI escape sequences" but VT100 control codes (which were defined long before there were graphical terminals and terms like "RGB").



来源:https://stackoverflow.com/questions/15682537/ansi-color-specific-rgb-sequence-bash

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!