Skip to content

Consider replacing anstyle-lossy with prettypretty #200

@apparebit

Description

@apparebit

Hi,

nice work! I happen to agree on much of the premise of this project and am also building a library, called prettypretty, to improve color output of terminal applications. But where this project seems to have focused on integration and interoperability with the ecosystem, I focused on the color science. I believe that both projects have complementary strengths and would benefit from each other. Concretely, I am suggesting that you replace the anstyle-lossy crate ("Lossy") with prettypretty because you'll get much better color conversions. Before I share results and on a more personal level, it was really cool discovering that we independently came up with the same color conversion algorithm based on a brute force search for the closest color.

I spent some time earlier today trying to understand the source for Lossy's color math and couldn't quite discern whether the author is confused about color science or just using language and symbols in ways that are unfamiliar to me. I do know of at least one expert who similarly abuses the term "perceptually uniform," so I can't decide. But in either case, basing one's color matching experiments on an RGB cube without defining either base color space or the new primaries and without accounting for test subjects' differences in color vision is a recipe for meaningless results. Assuming that the color space really is sRGB, those 64 colors are not even remotely close to being distributed in a perceptually uniform manner—as you can see in the plots of chroma/hue pairs and lightness values after conversion to Oklab, a color space that comes closer to being perceptually uniform than most. The rainbow line is the boundary of the sRGB gamut and the chart is labelled 60+4 because 4 colors are grays and they all sit on the origin.

colors

Suffice to say, that this is not a space where Euclidian distance is an accurate reflection of color distance. But maybe the weights make all the difference. I performed some experiments:

  • Inputs: all colors in the 6x6x6 RGB cube embedded in 8-bit terminal colors
  • Color processing: Convert embedded RGB to 24-bit color and then convert result to ANSI colors using:
    * Lossy's brute force search for the closest match in sRGB with Lossy's distance metric
    * Prettypretty's independent implementation of the same algorithm but using prettypretty's high-resolution colors with floating point coordinates, the Oklrab color space (a slight improvement on the above mentioned Oklab), and an unweighted Euclidian distance metric
    * My own conversion algorithm: I developed it after noticing some pathological results from closest match search. It exploits the semantics of ANSI colors, which come in pairs of regular and bright colors, and uses hue to select the closest pair and then lightness to select the closest matching color, all in Oklrch, the cylindrical version of Oklrab.
  • Contextual state: Prettypretty uses the terminal's theme colors, which were the "Basic" theme for Apple's Terminal.app, a saturated and bright theme, with colors having the same hues as the sRGB primaries and secondaries.

Before I share the three color grids for the three algorithms, here is the color grid without downsampling but showing the input colors:

Screenshot 2024-07-10 at 2 22 06 PM

Here are the results of Lossy's algorithm:

Screenshot 2024-07-10 at 2 21 28 PM

The color ramps on the right show that the algorithm is sensitive to luminance but its coordinate space and metrics push it towards the grays.

Here are the results for the Oklrab version with high-resolution colors:

Screenshot 2024-07-10 at 2 21 40 PM

The ramps are more fractured and there are fewer grays, both improvements in my mind.

Here is my own algorithm:

Screenshot 2024-07-10 at 2 21 54 PM

Since it matches colors and grays to colors and grays only, the grays are limited to single cells on the diagonal from upper-left to lower-right corner, and the colors dominate. There also are more graduations. Arguably, it's a bit heavy on the bright reds and might benefit from a weight to bias red selection towards the darker tone.

Still, prettypretty clearly outperforms Lossy and also has more options for other conversions as well as color manipulation in general. So please do consider replacing anstyle-lossy with prettypretty. Or, since you are really good at interfacing with the ecosystem, do offer an option that enables prettypretty as the color engine.

Cheers!

Robert

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions