在 JS 中,找到白色背景上不透明度为 0.5 的颜色?

In JS, find the color as if it had 0.5 opacity on a white background?

  1. 我有一个初始颜色:#3F92DF(蓝色)。

  2. 我可以降低它的不透明度,这会导致更浅的蓝色(如果在白色背景上):rgba(63, 146, 223, 0.5).

  3. 这种在白色背景上不透明的颜色,如果我选择它的颜色,我会得到:#A5CAEF.

问题是:在 JS 中,如何从 #3F92DF (1) 中找到 #A5CAEF (3)? IE。发现颜色好像在白色背景上具有 0.5 的不透明度?

我尝试使用初始颜色的 RGB 值(通过将它们增加到 255),但我无法获得预期的颜色(我得到的颜色更像绿松石色)。

var initialColor = "#3F92DF";
var colorWithOpacity = "rgba(63, 146, 223, 0.5)";
var colorWithoutOpacity = "#A5CAEF";

document.getElementById("d1").style.backgroundColor = initialColor;
document.getElementById("d2").style.backgroundColor = colorWithOpacity;
document.getElementById("d3").style.backgroundColor = colorWithoutOpacity;
div {
  width: 100px;
  height: 100px;
  border: solid 1px white;
  float: left;
}
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>

您需要使用颜色 mixing 在这种情况下使用标准公式:

newComponent = floor(oldComponent x alpha + backgroundComponent x (1 - alpha))

结果值通常是 floored(十进制截止)。

然而,话虽这么说,实际值取决于几件事:一个当然是较小的舍入误差,还有系统和浏览器如何处理 gamma(系统以实际伽马值为准)。

一般来说,混合应该总是在 linear color-space 中进行(即不应用 gamma)。由于这些原因,实际结果值可能与您在系统和您使用的浏览器中获得的值不同。

如果右下方的结果颜色与中间颜色不同,则表示浏览器未正确处理伽玛,您必须手动解码和重新编码伽玛(此处未显示),例如使用sRGB 用于近似,因为我们必须猜测系统的实际伽马。该过程将是:使用反伽马解码、混合、使用伽马重新编码。

无论如何,为了简单起见,您可以忽略上面关于伽玛的部分。使用上面的公式,没有 gamma 处理,在大多数情况下,在较新的浏览器中,我们会得到:

var initialColor = "#3F92DF";
var colorWithOpacity = "rgba(63, 146, 223, 0.5)";

// mix with white background:
var a = 0.5;
var r = Math.floor(0x3F * a + 0xff * (1 - a));
var g = Math.floor(0x92 * a + 0xff * (1 - a));
var b = Math.floor(0xDF * a + 0xff * (1 - a));

var colorWithoutOpacity = "#" + (r<<16 | g<<8 | b).toString(16);

// show result
document.getElementById("d1").style.backgroundColor = initialColor;
document.getElementById("d2").style.backgroundColor = colorWithOpacity;
document.getElementById("d3").style.backgroundColor = colorWithoutOpacity;
div {
  width: 100px;
  height: 100px;
  border: solid 1px white;
  float: left;
}
<div id="d1"></div><div id="d2"></div><div id="d3"></div>