[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#41544: 26.3; Possible incorrect results from color-distance
From: |
Mattias Engdegård |
Subject: |
bug#41544: 26.3; Possible incorrect results from color-distance |
Date: |
Mon, 8 Jun 2020 15:11:36 +0200 |
6 juni 2020 kl. 20.27 skrev Eli Zaretskii <eliz@gnu.org>:
> What practical problem is being solved here?
The current predicates for determining whether a colour is light or dark are
just bad. We can and should do better, and that's what this is all about.
Let's consider the three saturated colours #ff0000 (red), #00ff00 (green) and
#0000ff (blue). Black text looks terrible on blue, as does white on green;
black on red isn't good either. This comes as no surprise: the human eye is
more sensitive to brightness levels of green than blue, with red somewhere
in-between.
(These three colours just serve as illustrative examples; large chunks of the
RGB space will share the same properties.)
How do the existing predicates do? Let's call them MAX, AVG and DIST.
MAX: dark iff max(r,g,b) < 0.5
This classifies saturated red and blue as light, which is clearly terrible.
AVG: dark iff (r+g+b) / 3 < 0.6
This classifies saturated green as dark, which is also wrong.
DIST: dark iff (color-distance c "black") ≤ 292485
This one also thinks saturated green is dark. While the approach here looks
reasonable at first blush, it's really not: color-distance uses a simplified
expression for how dissimilar two colours are, but doesn't do a very good job
at determining brightness. For instance, its heavy blue weight makes no sense
when used in this way:
(color-distance "#ff0000" "black") => 162308
(color-distance "#00ff00" "black") => 260100
(color-distance "#0000ff" "black") => 194820
This means that we cannot fix DIST by tweaking its cut-off value; it's
fundamentally unfit for this purpose.
For a proper solution, we have theory to guide us: determine the perceived
brightness of a colour, and classify everything below a cut-off value as dark,
others as light. The patch uses a standard expression for relative luminance: Y
= 0.2126R + 0.7152G + 0.0722B, where R, G and B are linear colour components.
We assume a gamma of 2.2; it is nearly identical to the sRGB gamma curve and
the results are almost the same.
With a cut-off of 0.6, this predicate turns out to be quite good: much better
than MAX, AVG or DIST at any rate. While not perfect, it's good enough in the
sense that for colours where it seems to make the wrong decision, it's a fairly
close call, and the colour is quite readable with both black and write as
contrast.
I have tested it on several platforms and monitors, including 80x25 VGA
hardware text mode, and have yet to find a case where it fails, which
definitely cannot be said about the old predicates.
We can still tweak it: mainly the cut-off value (which is just experimentally
determined) but also the coefficients and the gamma correction. Although
technically valid, they aren't holy.
> This code's algorithm and rationale should be explained in the
> comments before we can discuss whether it's an improvement and why.
Thanks, I have improved this in the new patch.
This patch should also use the right coefficients (see above); I think I got
them wrong the first time.
0001-Improved-light-dark-colour-predicate-bug-41544.patch
Description: Binary data
- bug#41544: 26.3; Possible incorrect results from color-distance, (continued)
- bug#41544: 26.3; Possible incorrect results from color-distance, Drew Adams, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Eli Zaretskii, 2020/06/06
- bug#41544: 26.3; Possible incorrect results from color-distance, Simen Heggestøyl, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Simen Heggestøyl, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Simen Heggestøyl, 2020/06/08
- bug#41544: 26.3; Possible incorrect results from color-distance, Eli Zaretskii, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Drew Adams, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance, Simen Heggestøyl, 2020/06/07
- bug#41544: 26.3; Possible incorrect results from color-distance,
Mattias Engdegård <=
- bug#41544: 26.3; Possible incorrect results from color-distance, Drew Adams, 2020/06/08
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/08
- bug#41544: 26.3; Possible incorrect results from color-distance, Drew Adams, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Eli Zaretskii, 2020/06/09
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Eli Zaretskii, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Mattias Engdegård, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Eli Zaretskii, 2020/06/10
- bug#41544: 26.3; Possible incorrect results from color-distance, Simon Pugnet, 2020/06/04