RapierMother
RapierMother

Reputation: 369

How to combine two colors with varying alpha values

I have two colors, c₀ and c₁. They have variable alpha, red, green and blue values: (a₀, r₀, b₀, g₀) and (a₁, r₁, b₁, g₁). I'm wondering if there is a simple formula for combining these colors to obtain the correct new color (c₂).

Let's say that c₀ overlays c₁. I understand that if they had equal alpha values, then averaging their comparative red, green and blue values would do the trick. But when the alpha values differ, I'm noticing this doesn't work properly—it seems alpha determines the level at which each color's RGB values "contribute" to the final color.

Otherwise stated,

If a₀=a₁ then:
    a₂=a₀=a₁,
    r₂=(r₀+r₁)/2,
    g₂=(g₀+g₁)/2,
    b₂=(b₀+b₁)/2
Else:
    a₂=(a₀+a₁)/2,
    r₂=?,
    g₂=?,
    b₂=?

Upvotes: 13

Views: 10796

Answers (2)

user553965
user553965

Reputation: 1281

This is a python function that implements the above answer when both colors have the same alpha:


def mix_two_colors_with_alpha(hex_color1, hex_color2, alpha=0.5):
    """Returns a color that's equivalent to displaying input color2 
    on top of input color1 where both have the given alpha.
    """

    hex_color1 = hex_color1.lower().strip("#")
    hex_color2 = hex_color2.lower().strip("#")
    result = "#"
    for i in 0, 2, 4:
        rgb_value1 = int("0x"+hex_color1[i:i+2], 16)
        rgb_value2 = int("0x"+hex_color2[i:i+2], 16)
        # r2 over r1 = (1 - a0)·r1 + a0·r2
        new_rgb_value = int((1-alpha) * rgb_value1 + alpha * rgb_value2)
        new_rgb_hex = hex(new_rgb_value).upper()
        result += new_rgb_hex[2:]
    return result

Example:

mix_two_colors_with_alpha("#FF80BF", "#004AC0", alpha=0.4) 

returns '#996ABF'

Upvotes: 1

vadzim
vadzim

Reputation: 521

Short answer:

if we want to overlay c0 over c1 both with some alpha then

a01 = (1 - a0)·a1 + a0

r01 = ((1 - a0)·a1·r1 + a0·r0) / a01

g01 = ((1 - a0)·a1·g1 + a0·g0) / a01

b01 = ((1 - a0)·a1·b1 + a0·b0) / a01

Note that division by a01 in the formulas for the components of color. It's important.

Long answer:

The basic formula for the color when c0 overlays opaque c1 with alpha a0 is

r0 over 1 = (1 - a0)·r1 + a0·r0

// the same for g & b components

So if there is another color c2 and c1 actually is not opaque but has an alpha a1 we can overlay first c1 over c2 and then c0 over the resulting color.

r1 over 2 = (1 - a1)·r2 + a1·r1

r0 over (1 over 2) = (1 - a0)·((1 - a1)·r2 + a1·r1) + a0·r0

If we had a color c01 which overlays c2 with the same result as overlaying first c1 and then c0 it would be like this:

r01 over 2 = (1 - a01)·r2 + a01·r01

Ok, let's make them equal:

(1 - a01)·r2 + a01·r01 = (1 - a0)·((1 - a1)·r2 + a1·r1) + a0·r0 = (1 - a0)·(1 - a1)·r2 + (1 - a0)·a1·r1 + a0·r0

so

1 - a01 = (1 - a0)·(1 - a1) = 1 - ((1 - a0)·a1 + a0)

a01·r01 = (1 - a0)·a1·r1 + a0·r0

Upvotes: 31

Related Questions