寻找与“不透明”等同的颜色

说我有一个背景颜色与“色带”在另一个纯色运行。 现在,我希望色带部分透明,让一些细节融合在一起,但仍然保持色带在背景上“相同的颜色”。

有一种方法可以很容易地确定,对于给定的不透明度/ alpha <100%的色带颜色,它应该与背景中的100%不透明度相同的RGB值是什么?

这是一张照片。 背景是rgb(72, 28, 97) ,带rgb(45, 34, 70) 。 我想要一个rgba(r, g, b, a)的色带,使其看起来与这个纯色相同。

在这里输入图像说明

色彩混合只是每个通道的线性插值,对吗? 所以math很简单。 如果您在RGB2上使用RGBA1,则有效的视觉效果RGB3将为:

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

… alpha通道从0.0到1.0。

合理性检查:如果alpha是0,RGB3是否与RGB2相同? 是。 如果alpha是1,那么RGB3是否与RGB1相同? 是。

如果仅locking背景颜色和最终颜色,则会有大量的RGBA颜色(无限,在浮点空间中)可以满足要求。 所以,你必须select你想要的酒吧的颜色或不透明度水平,并找出其他的价值。

基于Alpha的颜色select

如果您知道RGB3(最终所需的颜色),RGB2(背景颜色)和A1(您想要多less不透明度),并且您只是在寻找RGB1,那么我们可以重新排列方程:

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

有一些理论上可能的颜色组合,但在标准的RGBA范围内是不可能的。 例如,如果背景为纯黑色,所需的感知颜色为纯白色,并且所需的alpha值为1%,则需要:

 r1 = g1 = b1 = 255/0.01 = 25500 

…超过任何可用的明亮的白色100倍。

基于颜色selectAlpha

如果您知道RGB3(最终所需的颜色),RGB2(背景颜色)和RGB1(您想要改变不透明度的颜色),并且您只是在寻找A1,如此排列方程:

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

如果这些给出不同的值,那么你不能完全匹配,但你可以平均阿尔法尽可能接近。 例如,世界上没有任何不透明的东西可以让你把红色变成蓝色。

我用Phrogz的答案做了一个很less的mixin。 你input:

  1. 颜色应该看起来如何
  2. 与一定的阿尔法
  3. 在给定的背景上(默认为白色)

代码如下:

 .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); } 

用法如下:

 @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); } 

显然不适用于不可能的组合(正如Phrogz所提到的那样),这意味着只支持轻微的透明度。 看看你如何去用它。

来自@Phrogz'回答:

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

所以:

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

所以:

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

请注意,您可以selecta1任何值,并会find所需的r1g1b1的相应值。 例如,select一个1的alpha告诉你,你需要RGB1 = RGB3,但是select一个0的alpha并不能解决(显然)。

感谢Phrogz的伟大的答案,这里是一个SASSfunction, 自动计算最佳的等效RGBA颜色。

您可以使用所需的颜色和现有的背景进行调用,并计算出最佳(意思是最透明的)等效的RGBA颜色,在每个RGB分量的±1/256范围内(由于舍入误差)给出所需的结果:

 @function alphaize($desired-color, $background-color) { $r1: red($background-color); $g1: green($background-color); $b1: blue($background-color); $r2: red($desired-color); $g2: green($desired-color); $b2: blue($desired-color); $alpha: 0; $r: -1; $g: -1; $b: -1; @while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0 or $r > 255 or $g > 255 or $b > 255) { $alpha: $alpha + 1/256; $inv: 1 / $alpha; $r: $r2 * $inv + $r1 * (1 - $inv); $g: $g2 * $inv + $g1 * (1 - $inv); $b: $b2 * $inv + $b1 * (1 - $inv); } @return rgba($r, $g, $b, $alpha); } 

我只是对一些组合(所有的Bootswatch主题)进行了testing,它适用于暗光和黑暗的结果。

PS:如果你需要比±1/256精度更好的颜色,你需要知道什么样的舍入algorithm浏览器适用于RGB颜色混合(我不知道这是否标准化),并添加一个合适的条件到现有的@while ,以便它不断增加$alpha直到达到所需的精度。