使用不透明度查找"等效"颜色

vic*_*vic 81 css colors css3

假设我有一个带有"色带"的背景色,并以另一种纯色在其上面运行.现在,我希望色带部分透明,让一些细节融合,但仍然保持色带在背景上的"相同颜色".

有没有办法(轻松)确定,对于给定的不透明度/ alpha <100%的色带颜色,它应该与背景上100%不透明度的颜色相同的RGB值是什么?

这是一张照片.背景是rgb(72, 28, 97),功能区rgb(45, 34, 70).我想要一个rgba(r, g, b, a)用于色带,使它看起来与这种纯色相同.

在此输入图像描述

Phr*_*ogz 117

颜色混合只是每个通道的线性插值,对吧?所以数学很简单.如果你有RGBA1而不是RGB2,有效的视觉效果RGB3将是:

r3 = r2 + (r1-r2)*a1
g3 = g2 + (g1-g2)*a1
b3 = b2 + (b1-b2)*a1
Run Code Online (Sandbox Code Playgroud)

... alpha通道的范围是0.0到1.0.

完整性检查:如果alpha为0,则RGB3与RGB2相同吗?是.如果alpha为1,则RGB3与RGB1相同吗?是.

如果仅锁定背景颜色和最终颜色,则可以满足要求的大量RGBA颜色(无限,在浮点空间中).因此,您必须选择条形的颜色或所需的不透明度级别,并找出另一个的值.

根据Alpha选择颜色

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

r1 = (r3 - r2 + r2*a1)/a1
g1 = (g3 - g2 + g2*a1)/a1
b1 = (b3 - b2 + b2*a1)/a1
Run Code Online (Sandbox Code Playgroud)

有一些理论上可能的颜色组合,但鉴于标准RGBA范围,这是不可能的.例如,如果背景是纯黑色,所需的感知颜色是纯白色,所需的alpha是1%,那么您需要:

r1 = g1 = b1 = 255/0.01 = 25500
Run Code Online (Sandbox Code Playgroud)

...超亮白色100倍比任何可用的更亮.

根据颜色挑选Alpha

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

a1 = (r3-r2) / (r1-r2)
a1 = (g3-g2) / (g1-g2)
a1 = (b3-b2) / (b1-b2)
Run Code Online (Sandbox Code Playgroud)

如果这些值给出不同的值,那么你就无法使它完全匹配,但你可以平均alpha值尽可能接近.例如,世界上没有任何不透明度会让你把绿色变成红色以获得蓝色.


eph*_*mer 12

我用Phrogz的答案做了一个LESS mixin.你输入:

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

}
Run Code Online (Sandbox Code Playgroud)

用法如下:

@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);
}
Run Code Online (Sandbox Code Playgroud)

显然不适用于不可能的组合(如Phrogz所述),这意味着只支持温和的透明度.看看你如何使用它.

  • @mixin bg_alpha_calc ($desired_colour, $desired_alpha, $background_colour: 白色) { $r3: 红色($desired_colour); $g3:绿色($desired_color);$b3:蓝色($desired_color);$r2:红色($background_color);$g2:绿色($background_color);$b2:蓝色($background_color);// 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; 背景颜色:$desired_color;背景颜色:rgba($r1, $g1, $b1, $desired_alpha); } (2认同)
  • 我采用并制作了一个 SCSS 版本的 mixin。在这里找到演示和代码:https://codepen.io/Grienauer/pen/Grogdx (2认同)

Tob*_*bia 7

感谢Phrogzephemer的伟大答案,这里有一个SASS功能,可以自动计算最佳等效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);
}
Run Code Online (Sandbox Code Playgroud)

我只是针对一些组合(所有的Bootswatch主题)进行了测试,并且它适用于暗光和暗光效果.

PS:如果你在得到的颜色中需要优于±1/256精度,你需要知道在混合rgba颜色时我们应用什么样的舍入算法(我不知道这是否标准化)并添加一个合适的现有的条件@while,使其不断增加,$alpha直到达到所需的精度.

  • 仅供参考,这个函数在Stylus中作为`transparentify()`存在:http://stylus-lang.com/docs/bifs.html#transparentifytop-bottom-alpha ...我在手动将其移植到Stylus之后发现了... (2认同)

Eri*_*ric 5

从@Phrogz的答案:

r3 = r2 + (r1-r2)*a1
g3 = g2 + (g1-g2)*a1
b3 = b2 + (b1-b2)*a1
Run Code Online (Sandbox Code Playgroud)

所以:

r3 - r2 = (r1-r2)*a1
g3 - g2 = (g1-g2)*a1
b3 - b2 = (b1-b2)*a1
Run Code Online (Sandbox Code Playgroud)

所以:

r1 = (r3 - r2) / a1 + r2
g1 = (g3 - g2) / a1 + g2
b1 = (b3 - b2) / a1 + b2
Run Code Online (Sandbox Code Playgroud)

请注意,您可以挑选任何价值a1,这将找到的相应值r1g1b1需要。例如,选择1的alpha值告诉您需要RGB1 = RGB3,但是选择0的alpha值不会产生任何解决方案(显然)。