Finding "equivalent" color with opacity

Say I have a background color with a "ribbon" running over it in another solid color. Now, I want the ribbon to be partially transparent to let some details blend through, but still keep the ribbon the "same color" over the background.

Is there a way to (easily) determine, for a given opacity/alpha < 100% of the ribbon color, what RGB values it should have to be identical to its color with 100% opacity over the background?

Here's a picture. Background is rgb(72, 28, 97) , ribbon rgb(45, 34, 70) . I want a rgba(r, g, b, a) for the ribbon so that it appears identical to this solid color.


Color blending is just a linear interpolation per channel, right? So the math is pretty simple. If you have RGBA1 over RGB2, the effective visual result RGB3 will be:

r3 = r2 + (r1-r2)*a1
g3 = g2 + (g1-g2)*a1
b3 = b2 + (b1-b2)*a1

…where the alpha channel is from 0.0 to 1.0.

Sanity check: if the alpha is 0, is RGB3 the same as RGB2? Yes. If the alpha is 1, is RGB3 the same as RGB1? Yes.

If you locked down only the background color and final color, there are a large number of RGBA colors (infinite, in floating-point space) that could satisfy the requirements. So you have to pick either the color of the bar or the opacity level you want, and find out the value of the other.

Picking the Color Based on Alpha

If you know RGB3 (the final desired color), RGB2 (the background color), and A1 (how much opacity you want), and you are just looking for RGB1, then we can re-arrange the equations thusly:

r1 = (r3 - r2 + r2*a1)/a1
g1 = (g3 - g2 + g2*a1)/a1
b1 = (b3 - b2 + b2*a1)/a1

There are some color combinations which are theoretically possible, but impossible given the standard RGBA range. For example, if the background is pure black, the desired perceived color is pure white, and the desired alpha is 1%, then you would need:

r1 = g1 = b1 = 255/0.01 = 25500

…a super-bright white 100× brighter than any available.

Picking the Alpha Based on Colors

If you know RGB3 (the final desired color), RGB2 (the background color), and RGB1 (the color you have that you want to vary the opacity of), and you are just looking for A1, then we can re-arrange the equations thusly:

a1 = (r3-r2) / (r1-r2)
a1 = (g3-g2) / (g1-g2)
a1 = (b3-b2) / (b1-b2)

If these give different values, then you can't make it match exactly, but you can average the alphas to get as close as possible. For example, there's no opacity in the world that will let you put green over red to get blue.


i made a LESS mixin using Phrogz' answer. you input:

  • how the colour should look
  • with a certain alpha
  • on a given background (default being white)
  • Here's the code:

    .bg_alpha_calc (@desired_colour, @desired_alpha, @background_colour: white) {
        @r3: red(@desired_colour);
        @g3: green(@desired_colour);
        @b3: blue(@desired_colour);
    
        @r2: red(@background_colour);
        @g2: green(@background_colour);
        @b2: blue(@background_colour);
    
        // r1 = (r3 - r2 + r2 * a1) / a1
        @r1: ( @r3 - @r2 + (@r2 * @desired_alpha) ) / @desired_alpha;
        @g1: ( @g3 - @g2 + (@g2 * @desired_alpha) ) / @desired_alpha;
        @b1: ( @b3 - @b2 + (@b2 * @desired_alpha) ) / @desired_alpha;
    
        background-color: @desired_colour;
        background-color: rgba(@r1, @g1, @b1, @desired_alpha);
    
    }
    

    Usage like so:

    @mycolour: #abc;
    @another_colour: blue;
    .box_overlay {
      // example:
      .bg_alpha_calc (@mycolour, 0.97, @another_colour);
      // or (for white bg) just:
      .bg_alpha_calc (@mycolour, 0.97);
    }
    

    Obviously doesn't work for impossible combinations (as mentioned by Phrogz), that means only mild levels of transparency are supported. See how you go with it.


    From @Phrogz' answer:

    r3 = r2 + (r1-r2)*a1
    g3 = g2 + (g1-g2)*a1
    b3 = b2 + (b1-b2)*a1
    

    So:

    r3 - r2 = (r1-r2)*a1
    g3 - g2 = (g1-g2)*a1
    b3 - b2 = (b1-b2)*a1
    

    So:

    r1 = (r3 - r2) / a1 + r2
    g1 = (g3 - g2) / a1 + g2
    b1 = (b3 - b2) / a1 + b2
    

    Note you can pick any value of a1 , and this will find the corresponding values of r1 , g1 , and b1 required. For example, picking an alpha of 1 tells you that you need RGB1 = RGB3, but picking an alpha of 0 gives no solution (obviously).

    链接地址: http://www.djcxy.com/p/15266.html

    上一篇: 用于选择类似于浅色的深色的算法

    下一篇: 用不透明度找到“等价”的颜色