Live data from Hacker News

Dithering in Colour

obrhubr.org

21–30 of 68 posts

Re: Dithering in Colour

#21
post #9

It might be worth using a lightness estimate like OKLab, OKLrab[1], or CIE Lab instead of the RGB luminance weighting, as it should produce a more perceptually accurate result. The other issue with your code right now, is that it is using euclidean distance in RGB space to choose the nearest color, but it would be probably also more accurate to use a perceptual color difference metric, a very simple choice is euclide…

If you are interested in color dithering with different color difference metrics [1], I've implemented just that [2]. You can find an example comparing metrics in my docs [3].

[1]: https://juliagraphics.github.io/Colors.jl/stable/colordiffer...

[2]: https://github.com/JuliaImages/DitherPunk.jl

[3]: https://juliaimages.org/DitherPunk.jl/stable/#Dithering-with...

Re: Dithering in Colour

#22

Dithering is something of a lost art now that our displays can handle millions of colors in high definition, but it can be a striking artistic effect. If anyone thinks their websites are too colorful, I made a pure JavaScript web component to dither images on client in real time, taking into account the real pixel size of the current display. https://sheep.horse/2023/1/improved_web_component_for_pixel-...

Very cool, but the image in the bottom of the page flickers when scrolling.

Re: Dithering in Colour

#23

Dithering is something of a lost art now that our displays can handle millions of colors in high definition, but it can be a striking artistic effect. If anyone thinks their websites are too colorful, I made a pure JavaScript web component to dither images on client in real time, taking into account the real pixel size of the current display. https://sheep.horse/2023/1/improved_web_component_for_pixel-...

Very cool, but the image in the bottom of the page flickers when scrolling.

Dithering does that !

Re: Dithering in Colour

#24
Did the author forget to finish the blog post?

They show a single example of incorrect dithering, explain it's wrong, and then don't show a corrected version. There isn't a single example of proper color dithering.

And they talk about the distance to the nearest color (RGB) but don't explain how to account for black or white -- how to trade off between accuracy of hue, brightness, and saturation, for example.

This post doesn't explain at all how to actually dither in color. I don't understand why this is on the front page with over 50 votes.

Re: Dithering in Colour

#25
post #10

> Dithering a black-to-white gradient will be wrong without linearising first. TBH both look wrong to me. If I squint, neither dithering patterns match the original gradient... but the non-linearized one looks the most similar. What could be causing this?

You're looking at a scaled version of the bitmap (potentially re-scaled multiple times) and some or all of those interpolations may not have been done in a linear colour space.

But in this case I think it's just wrong. The entire first 40% of the bar is black, and I don't think it should be.

Re: Dithering in Colour

#26
post #10

> Dithering a black-to-white gradient will be wrong without linearising first. TBH both look wrong to me. If I squint, neither dithering patterns match the original gradient... but the non-linearized one looks the most similar. What could be causing this?

I don't know where they got the idea you don't dither in srgb, the point of dithering is to map it to the nearest bit pattern with a random adjustment so that it could go either way(aside from artistic choice), you should dither in srgb if you are going to display it in srgb, which is probably why the "not linearized" version looks more accurate. See: Dithering should happen in sRGB https://www.shadertoy.com/view/Nss…

I'm far from convinced that shadertoy demonstration is correct: If you set the number of bits to 1, the dithered version is clearly far too light, which is exactly what happens if you dither in gamma-encoded space rather than linear space.

It gets much worse if you uncomment the SHOW_CORRECT define since the data is then being transformed back to SRGB before being quantised, which quite heavily skews the probability of which code point will be selected in favour of the lighter colour.

Increasing the number of bits hides the effect somewhat by making more code points available. But because they're distributed in gamma-encoded rather than linear-encoded space, it's still not correct to assume that a 50/50 pixel mix of two adjacent code points will appear the same as the colour numerically halfway between them, unless you're making that judgement in linear space.

The mistake the shadertoy is making is transforming the data to sRGB before quantising. Both dithering and quantising should be done in linear space (which is non-trivial since in linear space the codepoints aren't linearly distributed any more) - otherwise the dither function's triangular distribution is skewed by the sRGB transform.

Re: Dithering in Colour

#27
Error diffusion dithering is kind of old fashioned. It is a great algorithm where you only need to go though the image once, pixel by pixel. But it doesn't work well with todays hardware, especially GPUs. Would be fun to come up with new algorithms that are better parallelizable.

Re: Dithering in Colour

#29

Error diffusion dithering is kind of old fashioned. It is a great algorithm where you only need to go though the image once, pixel by pixel. But it doesn't work well with todays hardware, especially GPUs. Would be fun to come up with new algorithms that are better parallelizable.

Deterministic random value dithering, where the chance of being the dithered color or not is based on the percentage that the true value is that color?

Re: Dithering in Colour

#30
post #9

It might be worth using a lightness estimate like OKLab, OKLrab[1], or CIE Lab instead of the RGB luminance weighting, as it should produce a more perceptually accurate result. The other issue with your code right now, is that it is using euclidean distance in RGB space to choose the nearest color, but it would be probably also more accurate to use a perceptual color difference metric, a very simple choice is euclide…

I moved my canvas library's reduce-palette filter over to OKLAB calculations a while back. The calculations are more computationally intensive, but worth the effort.

https://scrawl-v8.rikweb.org.uk/demo/filters-027.html

Post reply on HN