Advanced Color Calculator

by Marshall Farrier|2/20/10

In this article I'd like to deal with some complexities that were omitted in my Simple Formulas for Calculating Tints and Shades. These complications arise when one attempts a more exact treatment of color saturation.

I should point out that here, as in my previous examination of color, I intend to treat only the mathematics of color--whether or not it corresponds to the way in which we perceive it. So, for example, mixing 50% black (#000) with 50% white (#fff) just is the specific gray specified by the rgb value #808080. It is a different issue whether the human eye perceives this gray to be halfway between white and black. While the possible discrepancy in this case may seem insignificant, it can become noticeable when we step through the various shades one step at a time. The following grayscale begins with black and increases the amount of white by 10% at each step:

Most people will likely perceive some of these steps as larger than others, although the difference in the numeric values is the same each time (with negligible exceptions due to rounding). The distance between the steps, however, isn't the important issue here. I'm concerned here only with determining which specific rgb values belong to the range of tints and shades of a particular coloer and which ones don't.

Saturation

I'm going to call rgb colors saturated when 1) the maximum of the 3 rgb values is 255 and 2) the minimum of these values is 0. Any rgb color that is not itself a graytone can be represented uniquely as a mixture of gray and a fully saturated color. Let's take the 3-tuple (a0, b0, c0) to be the rgb representation of a color other than gray, 0 <= g <= 255, and 0 <= p <= 1. g is going to represent the desired shade of gray, and p is going to be the percent of a saturated color present in a mixture that yields (a0, b0, c0). Since we know that (a0, b0, c0) is not a shade of gray, we can for ease of calculation permute the values so that a0 >= b0 >= c0 and a0 > c0. We then get the equations:

a0 = (p * 255) + ((1 - p) * g)
b0 = (p * b_sat) + ((1 - p) * g)
c0 = (1 - p) * g

We have 3 unknowns here (p, g and b_sat) and 3 equations, so we have a unique solution for p, g and b_sat as long as the equations are independent, as they clearly are when a0 > b0 > c0 (and when b0 = a0 or b0 = c0 we get 2 independent equations with 2 unknowns).

The spreadsheet zipped up in gui_color_1_0.zip solves these equations in 2 steps: First, I extract all black from the original color (just like the simple spreadsheet), then I extract all white from the result of the black extraction (unlike the simple spreadsheet). I'll leave it to the reader to verify that these steps amount to extracting gray. They also yield numbers that make it easy to figure the proportions of gray and saturated color present in the original unsaturated color. Here are some saturation ranges for the same set of colors I used in the previous version. The saturation level nearest the original color is indicated by a dotted border. Also note that the "gray" for the melon and for the green is actually white--i.e., no black was present in the orginal color.

Melon (#fff through #ff9800):
Green (#fff through #98ff00):
Brown (#b2b2b2 through #ffad00):
Blue (#4a4a4a through #00b1ff):

It's interesting to see here how brown results from mixing gray (71.8%) with orange (28.2%).

Also worth noting is that any given saturated color will have different "desaturation paths" depending on which shade of gray we use in the desaturation mix. So, we can't simply desaturate a given color but instead can only desaturate it using a particular gray-tone.

Shades Revisited

Now that we know how to specify any color as a unique mixture of gray and some saturated color, how do we apply this knowledge to the problem of specifying shades and tints? Starting with a color (a0, b0, c0) for which we assume a0 > b0 > c0, our spreadsheet resolves this color into a fully saturated color, a saturation percentage and a graytone, all of which are unique to the given color. In other words, we have determined the values b_sat, p0 and g0 such that:

a0 = (p0 * 255) + ((1 - p0) * g0)
b0 = (p0 * b_sat) + ((1 - p0) * g0)
c0 = (1 - p0) * g0

In order to have black as the darkest shade of our original color, we must not only increase the amount of gray used but also successively darken the gray toward black. The obvious formula for shades of (a0, b0, c0) is thus:

x = (p * p0 * 255) + ((1 - (p * p0)) * p * g0)
y = (p * p0 * b_sat) + ((1 - (p * p0)) * p * g0)
c0 = (1 - (p * p0)) * p * g0

The following shading sequences show the colors resulting from these equations and bring out an additional difficulty:

Melon (#2a2317 through #ffb13d):
Green (#232a17 through #b1ff3d):
Brown (#181611 through #c8b180):
Blue (#07090a through #405963):

This method limits us for shading when the starting color (our blue, for example) is already pretty dark. More useful would be a new color relative to which this blue is a shade. We want to be able to work not only with shades of our original color, but in some cases, we may want to create a color of which the original color is itself a shade. The formulas in the color_var1 worksheet identify various colors of this sort. If, for example, we choose the more middle-of-the-road gray defined by decimal 160 rather than the dark gray (decimal 75) originally used, we can modify our scale of blue shades as follows:

Blue (#0f1417 through #6fa5bc):

The worksheet color_var2 performs the same calculations when our original color is too light and we want it to appear as a tint of an unknown base color.

Tints

The same methods can be applied to tints. Since the formulas all follow the same principles for tints as they do for shades (simply replacing black with white), I won't go through their derivation but will simply show the scale of tints resulting from these formulas. I'll also use the lighter shade of blue from the preceding section:

Melon (#ffb13d through #fff7eb):
Green (#b1ff3d through #f7ffeb):
Brown (#c8b180 through #f7f5f0):
Blue (#6fa5bc through #eef3f5):

Download: gui_color_1_0.zip

articles

This site is currently being re-organized. As a result, several of the navigation choices above may not yet be active.