Re-calculating colors for opacity

Achieving the same resulting color by mixing different colors at different opacities
Each blob has different color and opacity, but the mixed color (over background) is the same

When working with images and websites I deal with many different tricks and challenges, but some of them slightly more often than others.

Context

Suppose I'm making a Firefox mini-theme using Firefox Color.

I pick the colors that I like, but then I decide to add a pattern too.

And patterns are cool, but they apply to the background, not the toolbar:

But I do want the pattern on the toolbar! So now what?

I could wiggle the color and opacity sliders until it looks roughly the same as before while being semi-transparent, but how transparent can we get, anyway?

Fortunately, with just a little math, it is possible to calculate a color for given transparency that will produce identical or near-identical[1] mixed color when drawn over a specified background color.

And thus:

If you'd like to snatch this theme, here's a link.

[1] Within ±1 unit on each channel because of rounding.

The math

The formula for painting a color over an opaque background goes like this:

output = background * (1 - alpha) + color * alpha

Therefore, to go backwards from that we'd need to:

color = (output - background * (1 - alpha)) / alpha

And to figure out the lowest possible opacity, we solve the formula for alpha instead:

alpha = (output - background) / (limit - background)

with limit being either minimum or maximum depending on whether the color's channel is higher or lower than that of the background.

Calculator

After writing the above formulas in a JavaScript console who knows how many times, I have finally decided to write this post and make a little calculator. Check it out:

Name Hex R G B
Back
Fore
Name Hex 0-255 0-1 0-100%
Alpha
Slider min: 8.29%
Result
Preview
So here you set a background color (what we're painting over), foreground color (what we're painting with), opacity in any convenient format, and get a color back that would produce foreground color when drawn over the background color with said opacity.

There is also a little preview so that it's slightly easier to tell what you're doing.


And that's about it!

Thanks for reading!

Related posts:

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.