Skip to content

Better color detail via other colorspaces (e.g. YDbDr) #128

Open

Description

I was trying a few things to get better results and found out transforming to YDbDr (which encodes blue/red chroma as the difference to luma), quantizing and remapping, then transforming back to sRGB preserves more color detail especially when requesting very low color counts.

Here are some of my 16-color results, which I obtained by using ImageMagick’s API to transform to YDbDr, passing it through libimagequant as if it were RGB, and reversing the color transformation.

original unmodified via YDbDr
original Image Image
Image Image Image
Image Image Image
Image Image Image

Of course this doesn’t always yield pretty results:

original unmodified via YDbDr
Image Image Image

However, there’s one more trick we can use in special cases: sigmoidal contrast adjustment before and after quantization (I did that in Oklch colorspace for this example).

unmodified via YDbDr sigmoidal contrast
Image Image Image

Just leaving this here as inspiration 🙂

With a custom color transform it might be possible to turn it into a color weighting option or something. I also haven’t tried playing with importance maps yet.

Activity

  1. kornelski commented on Jan 19, 2026

    @kornelski
    Member

    Thanks for the suggestion. I've checked the YDbDr, and like other YUV-like colorspaces I've experimented with, it wasn't an improvement overall.

    pngquant's algorithm requires more than 64 colors to work properly, and is tuned for 256 colors. 16 colors don't really work, because median cut is subdividing the color space along one axis at a time. The first few subdivisions are mostly meaningless, because they divide too many too dissimilar colors, and usually there isn't any straight line cut between them. A different color space rotates the space, so the first few cuts are done at a different angle that may be better for some images, but these are still coarse cuts, and it's mostly luck. Only later cuts start finding true boundaries between clusters of colors, which lets it separate saturated colors from the rest, but then the divisions are already more fine-grained and the clusters less mixed-up, so the color space aligning the cuts doesn't matter as much.

    I've found two problems with YUV-like color spaces:

    • the useful range and variance of UV channels is significantly different from the Y channel. For median cut it's critical to decide whether it should split on Y, U, or V, so it needs to have really good information about relative importance of each channel, but the channels are much harder to compare than RGB. Too much importance on Y desaturates, too little creates useless hues.

    • in simple colorspaces that are just an affine transform of sRGB, U/V channels depend on Y, and don't blend well. Gamma of UV channels is impossible to reason about. This is the kind of error you can see in JPEG or videos when you compress sharp red or cyan lines - instead of blurry red at the same brightness, you get brightness shifting when red blends with other colors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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