256 color and 24-bit true color support
See original GitHub issueThis backports upstream issue https://github.com/erikrose/blessings/issues/67 Some background: https://gist.github.com/XVilka/8346728 See also https://github.com/erikrose/blessings/pull/30#issuecomment-76576305
In brief: if number_of_colors
is 256, we can pretty safely assume to support emitting 256 colors, and this is currently possible with term.color(196)
or some such. However, as a “formatting name” it is deplorable. It would require using a reference guide to map colors-by-number. I actually spent some time trying to find a mapping and came up pretty short, I guess you would run a script that emits all 256, pick the one you like, and note it down.
As an API, supporting {t.bold_color196}
is very much against the “easy to write, easy to read” philosophy that Blessings encourages. What follows is my draft proposal.
rgb method
@property
def rgb(self, red, green, blue)
"""
Return a callable accepting arguments ``(red, green, blue)``, which emit a sequence approximated to the colorspace of the terminal bound by :attr:`number_of_colors`. The values of each color are 0-255.
(...)
"""
This would be exactly like the existing color(n)
, except if given rgb(255, 50, 100)
on a terminal where number_of_colors
is 16, this would be “coerced” (or downsampled) as though you called rgb(255, 85, 85)
which is exactly the expected color in the CGA palette, emitting the exact same sequence of term.bright_red
or color(12)
.
true_colorspace context manager
@contextmanager.contextlib
def true_colorspace():
"""
Context manager that enables mapping of compound color names and :attr:`rgb` values
to a True color (24-bit, 16,777,216 colors) colorspace.
"""
This is necessary as a context manager: we cannot determine whether the given terminal emulator supports true colors: There is no xterm-16777216color
terminal name, or anything like it. There is no situation that I know of where the terminal capability database for number_of_colors
could return 16,777,216. A terminal emulator that supports it provides no method to query whether or not it supports it. For those who know their intended audience/emulator, they may rightly go ahead and use them, or provide configuration to enable it through the use of such context manager.
Compound Formatters as X11 color names
Use the official X11 color names, http://en.wikipedia.org/wiki/X11_color_names as compound formatters. These are mapped by their hexidecimal values to rgb() to emit the appropriate sequence. This allows one to use “deep_pink”, which is (255, 20, 147), but on a 16-color terminal it would be mapped to the same sequence as term.bright_red.
Issue Analytics
- State:
- Created 8 years ago
- Reactions:1
- Comments:28 (16 by maintainers)
Top GitHub Comments
I started working on this. Changes pushed to the color branch.
So far I have dictionaries mapping 8, 16, 88, and 256 color indexes to RGB values. There’s also a dictionary mapping x11 color names to RGB values and a color translator, which supports caching and finds the color closest to the given RGB values in the supported range. In Terminal I added truecolor detection based on what I could find. It’s likely to be accurate when detecting true color support, but will miss some. The nice part is, the workaround is just to set an environment variable.
Where I hit a wall was in implementing the methods/properties in Terminal. With truecolor support,
\x1b[38;2;<r>;<g>;<b>m
(foreground) and\x1b[48;2;<r>;<g>;<b>m
(background) should provide the correct sequences. But I would think we’d want to downconvert to use color() with an index if truecolor support isn’t detected. If it’s flexible like that, can it still be a property? The sequence and inputs would be different depending on the situation. Not sure if there’s already a way to handle that.I hadn’t seen that. We could add it in and see how it compares. I’m not sure I understand it enough to document it. These seems to assume the 256 color pallette is a summary of a larger color space, but I’m not sure that’s true. We also haven’t implemented weighted HSV like you suggested. Doing simple HSV is easy, but I’m not sure what the weighting would need to be.
It might be worth pulling the conversion algorithms out into their own package. They probably have more utility independently and will get eyes on them from color people rather than just terminal application people. There are some packages that already do this, colour-science, colorio, and colormath, but they tend to do a lot more and have heavy requirements like numpy, scipy, and/or matplotlib.