获取叠加颜色(元素)的rgb
Get the rgb of overlaying colors (elements)
假设我有以下设置
body {
background: rgba(0,0,0,0.5);
}
#first {
width: 200px;
height: 100px;
background: rgba(255,0,0,0.5);
}
#second {
width: 50px;
height: 50px;
background: rgba(86, 185, 11, .5);
position: absolute;
top: 20px;
left: 20px;
}
如何get/calculate #second
div 的颜色?
我截取了 div 的屏幕截图并在 Photoshop 中检查了它们的 RGB。
Body -> 128,128,128
First red div -> 192,65,65
Second yellowish div -> 140,125,38
我通过实验找到了计算第一个 div 的 rgb 的方法。将两个值相加,然后应用 alpha。
R: (128 + 255) * 0.5 = 191.5
G: (128 + 0) * 0.5 = 64
B: (128 + 0) * 0.5 = 64
第二次尝试使用相同的方法div,但现在变得更棘手了。
R: (((128 + 255) * 0.5) + 86) * 0.5 = 138.5
G: (((128 + 0) * 0.5) + 185) * 0.5 = 124.5
B: (((128 + 0) * 0.5) + 11) * 0.5 = 37.5
我可以四舍五入 G 和 B 以获得准确的结果,但 R 相差 1.5。如果我增加颜色层的数量,我不知道会得到什么样的结果。
有没有更好的计算方法?
Update :正如 Kaiido 所建议的,我尝试使用 canvas。使用矩形创建相同的东西:Fiddle。使用 getImageData
提取第二个矩形的 rgb。返回值为 [122, 105, 6, 223]
。不习惯使用 8 位整数作为 alpha 值,所以它是 [122, 105, 6, 0.8754]
。尽管我提取了一些 rgb 值,但它不是纯色,而且绝对不是我在 Photoshop 中测得的 140,125,38
.
另外,当我截取 canvas 的屏幕截图并检查第二个矩形的颜色时,它是 139, 124, 37
,但是 #second div 的颜色是 140,125,38
.它们并不完全相同。
无论如何,我搜索了一种方法将返回值从 getImageData
即 122, 105, 6, 0.8754
转换为 140,125,38
。我想如果我用下面的例子来补偿缺失的不透明度,我会得到想要的值
122 * (255/223) = 139.5 // 140
105 * (255/223) = 120 // 125
6 * (255/223) = 6.86 // 38
我为 R 做了,但同样的方法对 G 和 B 不起作用。我开始认为 canvas 不会真正有帮助,除非有一种方法可以将透明颜色转换为纯色。
使用 Kaiido 的方法,我设法使用 canvas 获得了叠加颜色的最终结果。
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// default background
context.beginPath();
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "white";
context.fill();
// body
context.beginPath();
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgba(0,0,0,.5)";
context.fill();
// first div
context.beginPath();
context.rect(10, 10, 200, 100);
context.fillStyle = "rgba(255,0,0,0.5)";
context.fill();
// second div
context.beginPath();
context.rect(20, 20, 50, 50);
context.fillStyle = "rgba(86, 185, 11, .5)";
context.fill();
var imageData = context.getImageData(25, 25, 1, 1).data;
console.log(imageData); // 139,124,37
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
虽然这给了我想要的东西,但我仍然想在数学上这样做。
假设我有以下设置
body {
background: rgba(0,0,0,0.5);
}
#first {
width: 200px;
height: 100px;
background: rgba(255,0,0,0.5);
}
#second {
width: 50px;
height: 50px;
background: rgba(86, 185, 11, .5);
position: absolute;
top: 20px;
left: 20px;
}
如何get/calculate #second
div 的颜色?
我截取了 div 的屏幕截图并在 Photoshop 中检查了它们的 RGB。
Body -> 128,128,128
First red div -> 192,65,65
Second yellowish div -> 140,125,38
我通过实验找到了计算第一个 div 的 rgb 的方法。将两个值相加,然后应用 alpha。
R: (128 + 255) * 0.5 = 191.5
G: (128 + 0) * 0.5 = 64
B: (128 + 0) * 0.5 = 64
第二次尝试使用相同的方法div,但现在变得更棘手了。
R: (((128 + 255) * 0.5) + 86) * 0.5 = 138.5
G: (((128 + 0) * 0.5) + 185) * 0.5 = 124.5
B: (((128 + 0) * 0.5) + 11) * 0.5 = 37.5
我可以四舍五入 G 和 B 以获得准确的结果,但 R 相差 1.5。如果我增加颜色层的数量,我不知道会得到什么样的结果。
有没有更好的计算方法?
Update :正如 Kaiido 所建议的,我尝试使用 canvas。使用矩形创建相同的东西:Fiddle。使用
getImageData
提取第二个矩形的 rgb。返回值为 [122, 105, 6, 223]
。不习惯使用 8 位整数作为 alpha 值,所以它是 [122, 105, 6, 0.8754]
。尽管我提取了一些 rgb 值,但它不是纯色,而且绝对不是我在 Photoshop 中测得的 140,125,38
.
另外,当我截取 canvas 的屏幕截图并检查第二个矩形的颜色时,它是 139, 124, 37
,但是 #second div 的颜色是 140,125,38
.它们并不完全相同。
无论如何,我搜索了一种方法将返回值从 getImageData
即 122, 105, 6, 0.8754
转换为 140,125,38
。我想如果我用下面的例子来补偿缺失的不透明度,我会得到想要的值
122 * (255/223) = 139.5 // 140
105 * (255/223) = 120 // 125
6 * (255/223) = 6.86 // 38
我为 R 做了,但同样的方法对 G 和 B 不起作用。我开始认为 canvas 不会真正有帮助,除非有一种方法可以将透明颜色转换为纯色。
使用 Kaiido 的方法,我设法使用 canvas 获得了叠加颜色的最终结果。
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// default background
context.beginPath();
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "white";
context.fill();
// body
context.beginPath();
context.rect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgba(0,0,0,.5)";
context.fill();
// first div
context.beginPath();
context.rect(10, 10, 200, 100);
context.fillStyle = "rgba(255,0,0,0.5)";
context.fill();
// second div
context.beginPath();
context.rect(20, 20, 50, 50);
context.fillStyle = "rgba(86, 185, 11, .5)";
context.fill();
var imageData = context.getImageData(25, 25, 1, 1).data;
console.log(imageData); // 139,124,37
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
虽然这给了我想要的东西,但我仍然想在数学上这样做。