Mobile app version of vmapp.org
Login or Join
Turnbaugh909

: Automatically select a foreground color based on a background color What is the appropriate "formula" for a foreground color based on a background color (where the background color may be any

@Turnbaugh909

Posted in: #Background #Color #Text

What is the appropriate "formula" for a foreground color based on a background color (where the background color may be any color)?

More info:

I want to have my application select a foreground color based on a (solid even) background color. I was thinking along the lines of: black if the total of the RGB components is over (255x3)/2 , and white otherwise. But would rather get the opinion of the experts. Is there an accepted way to do this? Or what would you suggest?

There is a similar question but the answers basically offer to limit the available background colors. That's not an option in this case.

10.02% popularity Vote Up Vote Down


Login to follow query

More posts by @Turnbaugh909

2 Comments

Sorted by latest first Latest Oldest Best

 

@Cugini998

I answered a similar question on Game Development Stack Exchange a while ago, so let me summarize the answers there.

You idea of picking either black or white, depending on which one contrasts better with the background color, is sound. However, simply averaging the RGB components will not give a good indication of how light a particular color will appear to the human eye, for (mostly) two reasons:

First of all, for reasons related to human color perception, the red, green and blue channels do not have the same relative luminance; in fact, pure blue (#0000ff) is only about 10% as bright (and pure red only about 30% as bright) as pure green (#00ff00). Thus, e.g. black text on pure blue will never have a particularly good contrast.

For example, the images below show examples of black and white text on pure red, green and blue backgrounds (#ff0000, #00ff00 and #0000ff ):





You can clearly see the differences in contrast, even though all these colors have the same average RGB value.

The other complication is that the RGB color spaces normally used on computer screens (like sRGB) are not linear, but have a display gamma around 2 or so. That means that e.g. the RGB color #7f7f7f = "50% gray" does not actually appear half as bright as pure white (#ffffff), but rather only about 25% as bright, whereas the color that actually has a relative luminosity halfway between black and white is actually closer to "75% gray" (#bfbfbf).

Conveniently, though, the human eye is also non-linear, and is more sensitive to differences in darker shades. In fact, for shades of gray, the non-linearities roughly cancel out, so that the RGB 50% gray (#7f7f7f) is still perceptually about equally far from both black and white. As a demonstration, here is some black and white text on 25%, 50% and 75% gray backgrounds (#3f3f3f, #7f7f7f and #bfbfbf):





However, to accurate calculate the luminosity of an arbitrary RGB color, we do need to account for the display gamma, since it's the linear luminosity values that need to be averaged.

To put it all together, to determine whether black or white text would have better contrast on a background, you need to:


convert the gamma-compressed RGB color values into linear RGB,
take a weighted average of the linear R, G and B components, and
compare the resulting average against a suitable threshold.


The threshold value that gives best results may be determined experimentally, but one would generally expect it to lie close to the luminance of 50% RGB gray. In any case, it's worth noting that the perceived contrast will vary depending on the viewer's display settings and viewing conditions, so there is no single optimal value for everybody, but rather a fairly broad range of more or less equally good choices.

If you just want a simple formula to plug numbers into, try this:


if 0.2126 × Rγ + 0.7152 × Gγ + 0.0722 × Bγ > 0.5γ, choose black; else choose white,


where γ is the approximate display gamma value (γ = 2.2 is typical).

For an even simpler approximation, you can ignore the gamma correction (i.e. effectively assume that γ = 1) and just use the condition 0.2126 × R + 0.7152 × G + 0.0722 × B > 0.5. For shades of gray, this will make no difference (since we're applying the same gamma to both sides of the inequality), but it does somewhat overestimate the luminance of saturated colors. Fortunately, on such colors, both black and white tend to have decent contrast anyway, so the error may not matter much in practice.

Finally, note that, if the background color is not uniform, it's possible that no single text color may look good. In such cases, you may consider e.g. using black text with a white outline, or vice versa, or perhaps surrounding your text with a semitransparent box of the opposite color.

10% popularity Vote Up Vote Down


 

@Cofer715

Every colour has three variables; hue, saturation, and brightness.

Key to legibility is contrast which is can be optimised for each of the three variables independent of each other.

For example; the hue contrast can be optimised by finding its complement. The saturation contrast can be optimised by choosing opposites for each ground. Similarly, bright can be contrasted by dim.

This (above criteria) is in regard to only one formula for selection--Optimal Legibility.

There may be other considerations; aesthetic, perceptual, technical, etc.

One practical means of providing this capability has been to use a pre-determined, predictable, and acceptable result by using a Colour Look-Up Table that provides a set given one of the two. For example; given foreground of X, a background of Y is provided. Given a foreground of Y, a background of X is provided. The CLUT can be as complex or as comprehensive as desired for the particular application.

Once the values are known, their selection can be automated.

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme