如何将宜家灯泡颜色 XY(CIE 1931 色彩空间)转换为 RGB
how to convert Ikea light bulb color XY ( CIE 1931 colorspace ) to RGB
问题
我遇到了类似的问题:
How to convert CIE color space into RGB or HEX color code in PHP
如何将xy颜色转换为sRGB?
我无法让公式工作 xyY。我应该为 Y 输入什么?
环境设置
我有一个宜家灯泡,它在(CIE 1931 色彩空间)中给我一个 XY 颜色值
我想把它转换成 RGB,(sRGB) 或 HEX。
当通过全亮度和饱和度设置颜色时,Phosconn 应用程序正在发送以下 xy 值。
RED [0.735, 0.265]
GREEN [0.115, 0.826]
BLUE [0.157, 0.018]
我发现当我发送以下值时 lamp 显示更深的颜色:
RED [1.0, 0.0]
GREEN [0.0, 1.0]
BLUE [0.0, 0.0]
更准确地说,这是我试图实现的一个例子:
通过 zigbee 从灯泡(xy 颜色)检索信息,使用 javascript 将其转换为仪表板颜色选择器的 RGB 或 HEX
反之亦然。从仪表板的颜色选择器(RGB、亮度、饱和度)中检索信息,使用 JS 将其转换为 XY 颜色、亮度和饱和度,并使用 zigbee 将其发送到灯泡。
当前实施
它基于建议的 cie-rgb-color-converter NPM 模块。
function xyBriToRgb(x, y, bri){
// bri = bri/254*100
node.warn("XYBRI: "+x+ " | "+y+" | "+bri)
function getReversedGammaCorrectedValue(value) {
return value <= 0.0031308 ? 12.92 * value : (1.0 + 0.055) * Math.pow(value, (1.0 / 2.4)) - 0.055;
}
let xy = {
x: x,
y: y
};
let z = 1.0 - xy.x - xy.y;
let Y = bri / 255;
let X = (Y / xy.y) * xy.x;
let Z = (Y / xy.y) * z;
let r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
let g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
let b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
r = getReversedGammaCorrectedValue(r);
g = getReversedGammaCorrectedValue(g);
b = getReversedGammaCorrectedValue(b);
// Bring all negative components to zero
r = Math.max(r, 0);
g = Math.max(g, 0);
b = Math.max(b, 0);
// If one component is greater than 1, weight components by that value
let max = Math.max(r, g, b);
if (max > 1) {
r = r / max;
g = g / max;
b = b / max;
}
return {
r: Math.floor(r * 255),
g: Math.floor(g * 255),
b: Math.floor(b * 255),
};
}
msg.payload = xyBriToRgb(msg.payload.xy[0], msg.payload.xy[1], msg.payload.bri);
node.warn("RGB: "+ JSON.stringify(msg.payload))
return msg;
结果
let rgb = ColorConverter.xyBriToRgb(0.157 ,0.018, 6);
// return {r: 64, g: 0, b: 255}
研究Material
在这些优秀的人的帮助下,我找到了一些解释 Phillips HUE docs
这导致我 Review of RGB color spaces
与此同时,我在 phosconn api 或其灯泡固件中发现了一些错误,无法通过 api 设置饱和度。
我找到了 zigbee2mqtt 页面,它可以解决我所有的问题,页面 100% 适合宜家灯泡的型号 Zigbee2MQTT IKEA LED1624G9
我正在尝试为此设置 zigbee2mqtt,因为我在使用 phosconn 时遇到了一些问题,api 没有正确设置亮度和其他东西。
此外,亮度只是灯泡的亮度,与颜色无关,所以我假设它是特定于 phosconn 还是特定于灯泡?
您可以使用 cie-rgb-color-converter NPM 模块。
let xy = ColorConverter.rgbToXy(255, 0, 0);
// It returns {x: 0.7350000508904126, y: 0.26499994910958735}
xy
个数与题例相同
但是如果你想将这些数字转换回 RGB。您需要 Brightness
参数。
let rgb = ColorConverter.xyBriToRgb(0.7350000508904126 ,0.26499994910958735 , Brightness);
如果你设置Brightness
为0,它是最暗的光(没有光,没有颜色),RGB的所有数字返回为零,因为在零光下人眼什么都看不见。
以下示例是最接近的数字:
let rgb = ColorConverter.xyBriToRgb(0.7350000508904126 ,0.26499994910958735, 70);
// return {r: 255, g: 0, b: 16}
let rgb = ColorConverter.xyBriToRgb(0.11500021676131911 ,0.8259995753701338, 200);
// return {r: 0, g: 255, b: 0}
let rgb = ColorConverter.xyBriToRgb(0.15700016726803506 ,0.01799963360335173, 6);
// return {r: 64, g: 0, b: 255}
注意: cie-rgb-color-converter 有一个简单的问题,安装后转到 ColorConverter.js
并更改这些行:
let red = parseInt(r * 255) > 255 ? 255: parseInt(r * 255);
let green = parseInt(g * 255) > 255 ? 255: parseInt(g * 255);
let blue = parseInt(b * 255) > 255 ? 255: parseInt(b * 255);
red = Math.abs(red);
green = Math.abs(green);
blue = Math.abs(blue);
return {r: red, g: green, b: blue};
至
// Bring all negative components to zero
r = Math.max(r, 0);
g = Math.max(g, 0);
b = Math.max(b, 0);
// If one component is greater than 1, weight components by that value
let max = Math.max(r, g, b);
if (max > 1) {
r = r / max;
g = g / max;
b = b / max;
}
return {
r: Math.floor(r * 255),
g: Math.floor(g * 255),
b: Math.floor(b * 255),
};
@bokup 在 GitHub.
上发布它
简答
好的,所以我看到的是 1931 色度图的 xy 坐标?从中我们可以生成一个矩阵,通过矩阵我们可以生成 RGB 或 XYZ(和 xyY 在一个简单的进一步转换中。)
更长的答案
这些坐标是“xy”,不要与 XYZ 混淆(因为如果颜色科学会是什么这不是完全令人困惑吗?)
XYZ为颜色space,xyY为导数,xy为1931色度图坐标:
缺少 Y、亮度(光谱加权光),但让我们在 255 处求解所有三个原色,并假设它是白色。
我没有的一件事是“白点”...当您将 RGB 值设置为 255,255,255
时,白光的色温是多少?为了创建矩阵,我做了 D50 的假设,对于这样的照明来说是合理的......但它可能更低甚至更高。
矩阵的数学可以在 Bruce Lindbloom 的网站上看到:http://brucelindbloom.com
假设 255,255,255
产生接近 D50 的白光,那么从 XYZ 到 RGB 的矩阵是:
MATRIX
XYZ TO RGB
X
1.4628522474616900
-0.1840680708796900
-0.2743691849401830
R
Y
-0.5217863795540330
1.4472188263102400
0.0677218457168470
=
G
Z
0.0349375228787856
-0.0969021860977637
1.2885320438253000
B
但是等等...
您从哪里获得这些 xy 值?您的控制器似乎正在向每盏灯发送 255...所以,我对应用程序有点困惑?
假设在给定色温下所有三个都为 255 时为白色,则相对 Y 为 1.0(0.0 到 1.0 范围,但您也可以使用 0 到 100 范围)。
下一个问题是……线性度。在计算机显示器上,通常 sRGB 具有输出伽玛,功率曲线为 ^2.2 ... LED 灯泡可能没有。您是否正在尝试匹配电脑显示器?
假设不是,并且假设您的控制器也是 1 的伽马,那么 128,128,128 将是 0.5 的 Y
如果您想从 RGB 中获取整个 XYZ,矩阵就在这里:
用于参考 RGB 到 XYZ 和参考白点
MATRIX
RGB TO XYZ
R
0.7160822783599350
0.1009309426243870
0.1471718784550240
X
G
0.2581793248508610
0.7249474661542950
0.0168732089948435
=
Y
B
0.0000000000000000
0.0517819618681639
0.7733554122636590
Z
CALCULATED
REF WHITE POINT
WP
0.964185099439346
1.00
0.825137374131823
Matrix Sans Neo
矩阵生成后,处理起来相当简单。
将每一行的每个数字与输入通道的每一行相乘,然后求和,得到相应的输出。
所以对于输出到 RGB,你去
X * 1.46285 + Y * -0.184068 + Z * -0.274369 = R
X * 0.258179 + Y * 0.724947 + Z * 0.01687 = G
X * 0.0 + Y * 0.05178 + Z * 0.773355 = B
如果我能更好地理解您想要实现的目标,我可能会提供更多帮助。
重新计算的矩阵
用你给的白点:
FINAL RGB TO XYZ MATRIX
R 0.6491852651246980 0.1034883891428110 0.1973263457324920 X
G 0.2340599935483600 0.7433166037561910 0.0226234026954449 Y
B 0.0000000000000000 0.0530940431254422 1.0369059568745600 Z
CALCULATED REF WHITE POINT
WP 0.950000000000001 1.00 1.090000000000000
MATRIX INVERTED — XYZ TO RGB
X 1.6135957276619700 -0.2030358522440090 -0.3026422835182280 R
Y -0.5088917855729640 1.4114545750797300 0.0660482763436608 G
Z 0.0260574473801223 -0.0722725427335469 0.9610256584609440 B
问题
我遇到了类似的问题:
How to convert CIE color space into RGB or HEX color code in PHP
如何将xy颜色转换为sRGB? 我无法让公式工作 xyY。我应该为 Y 输入什么?
环境设置
我有一个宜家灯泡,它在(CIE 1931 色彩空间)中给我一个 XY 颜色值 我想把它转换成 RGB,(sRGB) 或 HEX。
当通过全亮度和饱和度设置颜色时,Phosconn 应用程序正在发送以下 xy 值。
RED [0.735, 0.265]
GREEN [0.115, 0.826]
BLUE [0.157, 0.018]
我发现当我发送以下值时 lamp 显示更深的颜色:
RED [1.0, 0.0]
GREEN [0.0, 1.0]
BLUE [0.0, 0.0]
更准确地说,这是我试图实现的一个例子:
通过 zigbee 从灯泡(xy 颜色)检索信息,使用 javascript 将其转换为仪表板颜色选择器的 RGB 或 HEX
反之亦然。从仪表板的颜色选择器(RGB、亮度、饱和度)中检索信息,使用 JS 将其转换为 XY 颜色、亮度和饱和度,并使用 zigbee 将其发送到灯泡。
当前实施
它基于建议的 cie-rgb-color-converter NPM 模块。
function xyBriToRgb(x, y, bri){
// bri = bri/254*100
node.warn("XYBRI: "+x+ " | "+y+" | "+bri)
function getReversedGammaCorrectedValue(value) {
return value <= 0.0031308 ? 12.92 * value : (1.0 + 0.055) * Math.pow(value, (1.0 / 2.4)) - 0.055;
}
let xy = {
x: x,
y: y
};
let z = 1.0 - xy.x - xy.y;
let Y = bri / 255;
let X = (Y / xy.y) * xy.x;
let Z = (Y / xy.y) * z;
let r = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
let g = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
let b = X * 0.051713 - Y * 0.121364 + Z * 1.011530;
r = getReversedGammaCorrectedValue(r);
g = getReversedGammaCorrectedValue(g);
b = getReversedGammaCorrectedValue(b);
// Bring all negative components to zero
r = Math.max(r, 0);
g = Math.max(g, 0);
b = Math.max(b, 0);
// If one component is greater than 1, weight components by that value
let max = Math.max(r, g, b);
if (max > 1) {
r = r / max;
g = g / max;
b = b / max;
}
return {
r: Math.floor(r * 255),
g: Math.floor(g * 255),
b: Math.floor(b * 255),
};
}
msg.payload = xyBriToRgb(msg.payload.xy[0], msg.payload.xy[1], msg.payload.bri);
node.warn("RGB: "+ JSON.stringify(msg.payload))
return msg;
结果
let rgb = ColorConverter.xyBriToRgb(0.157 ,0.018, 6);
// return {r: 64, g: 0, b: 255}
研究Material
在这些优秀的人的帮助下,我找到了一些解释 Phillips HUE docs 这导致我 Review of RGB color spaces
与此同时,我在 phosconn api 或其灯泡固件中发现了一些错误,无法通过 api 设置饱和度。
我找到了 zigbee2mqtt 页面,它可以解决我所有的问题,页面 100% 适合宜家灯泡的型号 Zigbee2MQTT IKEA LED1624G9
我正在尝试为此设置 zigbee2mqtt,因为我在使用 phosconn 时遇到了一些问题,api 没有正确设置亮度和其他东西。 此外,亮度只是灯泡的亮度,与颜色无关,所以我假设它是特定于 phosconn 还是特定于灯泡?
您可以使用 cie-rgb-color-converter NPM 模块。
let xy = ColorConverter.rgbToXy(255, 0, 0);
// It returns {x: 0.7350000508904126, y: 0.26499994910958735}
xy
个数与题例相同
但是如果你想将这些数字转换回 RGB。您需要 Brightness
参数。
let rgb = ColorConverter.xyBriToRgb(0.7350000508904126 ,0.26499994910958735 , Brightness);
如果你设置Brightness
为0,它是最暗的光(没有光,没有颜色),RGB的所有数字返回为零,因为在零光下人眼什么都看不见。
以下示例是最接近的数字:
let rgb = ColorConverter.xyBriToRgb(0.7350000508904126 ,0.26499994910958735, 70);
// return {r: 255, g: 0, b: 16}
let rgb = ColorConverter.xyBriToRgb(0.11500021676131911 ,0.8259995753701338, 200);
// return {r: 0, g: 255, b: 0}
let rgb = ColorConverter.xyBriToRgb(0.15700016726803506 ,0.01799963360335173, 6);
// return {r: 64, g: 0, b: 255}
注意: cie-rgb-color-converter 有一个简单的问题,安装后转到 ColorConverter.js
并更改这些行:
let red = parseInt(r * 255) > 255 ? 255: parseInt(r * 255);
let green = parseInt(g * 255) > 255 ? 255: parseInt(g * 255);
let blue = parseInt(b * 255) > 255 ? 255: parseInt(b * 255);
red = Math.abs(red);
green = Math.abs(green);
blue = Math.abs(blue);
return {r: red, g: green, b: blue};
至
// Bring all negative components to zero
r = Math.max(r, 0);
g = Math.max(g, 0);
b = Math.max(b, 0);
// If one component is greater than 1, weight components by that value
let max = Math.max(r, g, b);
if (max > 1) {
r = r / max;
g = g / max;
b = b / max;
}
return {
r: Math.floor(r * 255),
g: Math.floor(g * 255),
b: Math.floor(b * 255),
};
@bokup 在 GitHub.
上发布它简答
好的,所以我看到的是 1931 色度图的 xy 坐标?从中我们可以生成一个矩阵,通过矩阵我们可以生成 RGB 或 XYZ(和 xyY 在一个简单的进一步转换中。)
更长的答案
这些坐标是“xy”,不要与 XYZ 混淆(因为如果颜色科学会是什么这不是完全令人困惑吗?)
XYZ为颜色space,xyY为导数,xy为1931色度图坐标:
缺少 Y、亮度(光谱加权光),但让我们在 255 处求解所有三个原色,并假设它是白色。
我没有的一件事是“白点”...当您将 RGB 值设置为 255,255,255
时,白光的色温是多少?为了创建矩阵,我做了 D50 的假设,对于这样的照明来说是合理的......但它可能更低甚至更高。
矩阵的数学可以在 Bruce Lindbloom 的网站上看到:http://brucelindbloom.com
假设 255,255,255
产生接近 D50 的白光,那么从 XYZ 到 RGB 的矩阵是:
MATRIX | XYZ TO RGB | ||||
---|---|---|---|---|---|
X | 1.4628522474616900 | -0.1840680708796900 | -0.2743691849401830 | R | |
Y | -0.5217863795540330 | 1.4472188263102400 | 0.0677218457168470 | = | G |
Z | 0.0349375228787856 | -0.0969021860977637 | 1.2885320438253000 | B |
但是等等...
您从哪里获得这些 xy 值?您的控制器似乎正在向每盏灯发送 255...所以,我对应用程序有点困惑?
假设在给定色温下所有三个都为 255 时为白色,则相对 Y 为 1.0(0.0 到 1.0 范围,但您也可以使用 0 到 100 范围)。
下一个问题是……线性度。在计算机显示器上,通常 sRGB 具有输出伽玛,功率曲线为 ^2.2 ... LED 灯泡可能没有。您是否正在尝试匹配电脑显示器?
假设不是,并且假设您的控制器也是 1 的伽马,那么 128,128,128 将是 0.5 的 Y
如果您想从 RGB 中获取整个 XYZ,矩阵就在这里:
用于参考 RGB 到 XYZ 和参考白点
MATRIX | RGB TO XYZ | ||||
---|---|---|---|---|---|
R | 0.7160822783599350 | 0.1009309426243870 | 0.1471718784550240 | X | |
G | 0.2581793248508610 | 0.7249474661542950 | 0.0168732089948435 | = | Y |
B | 0.0000000000000000 | 0.0517819618681639 | 0.7733554122636590 | Z | |
CALCULATED | REF WHITE POINT | ||||
WP | 0.964185099439346 | 1.00 | 0.825137374131823 |
Matrix Sans Neo
矩阵生成后,处理起来相当简单。
将每一行的每个数字与输入通道的每一行相乘,然后求和,得到相应的输出。
所以对于输出到 RGB,你去
X * 1.46285 + Y * -0.184068 + Z * -0.274369 = R
X * 0.258179 + Y * 0.724947 + Z * 0.01687 = G
X * 0.0 + Y * 0.05178 + Z * 0.773355 = B
如果我能更好地理解您想要实现的目标,我可能会提供更多帮助。
重新计算的矩阵
用你给的白点:
FINAL RGB TO XYZ MATRIX
R 0.6491852651246980 0.1034883891428110 0.1973263457324920 X
G 0.2340599935483600 0.7433166037561910 0.0226234026954449 Y
B 0.0000000000000000 0.0530940431254422 1.0369059568745600 Z
CALCULATED REF WHITE POINT
WP 0.950000000000001 1.00 1.090000000000000
MATRIX INVERTED — XYZ TO RGB
X 1.6135957276619700 -0.2030358522440090 -0.3026422835182280 R
Y -0.5088917855729640 1.4114545750797300 0.0660482763436608 G
Z 0.0260574473801223 -0.0722725427335469 0.9610256584609440 B