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;249mTRUECOLORx1b[0m
"
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.