飞利浦色调,将 xy 从 api 转换为 HEX 或 RGB

Philips hue, convert xy from api to HEX or RGB

本文关键字:转换 HEX RGB api 色调 xy 飞利浦      更新时间:2023-09-26

我正在制作一个Web界面来管理我的色调灯,但是在颜色处理方面我很挣扎。

灯的 api 为我提供了 x 和 y 坐标,来自 http://en.wikipedia.org/wiki/CIE_1931_color_space

但不是 z 值。

我想我必须根据亮度值或饱和度值(0 到 255)计算 z。

但我对颜色和数学:p很糟糕。

我试图使用这些函数 https://github.com/eikeon/hue-color-converter/blob/master/colorconverter.ts

但正如我在评论中看到的那样,这些函数不提供正确的值......

有人可以在这里帮助我吗? ☺

PS:我需要一个JavaScript函数。

好的,所以我设法在以下的帮助下制作一些东西: 如何将 RGB 值转换为菲利普斯 Hue 灯泡的 XY 值

function xyBriToRgb(x, y, bri){
            z = 1.0 - x - y;
            Y = bri / 255.0; // Brightness of lamp
            X = (Y / y) * x;
            Z = (Y / y) * z;
            r = X * 1.612 - Y * 0.203 - Z * 0.302;
            g = -X * 0.509 + Y * 1.412 + Z * 0.066;
            b = X * 0.026 - Y * 0.072 + Z * 0.962;
            r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055;
            g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055;
            b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055;
            maxValue = Math.max(r,g,b);
            r /= maxValue;
            g /= maxValue;
            b /= maxValue;
            r = r * 255;   if (r < 0) { r = 255 };
            g = g * 255;   if (g < 0) { g = 255 };
            b = b * 255;   if (b < 0) { b = 255 };
            return {
                r :r,
                g :g,
                b :b
            }
        }

它不是非常精确,但它工作得很好。如果有人设法做得更好,请在此处发布,谢谢。

我修改了您的脚本以十六进制表示法返回 rgb 值:

function xyBriToRgb(x, y, bri)
{
    z = 1.0 - x - y;
    Y = bri / 255.0; // Brightness of lamp
    X = (Y / y) * x;
    Z = (Y / y) * z;
    r = X * 1.612 - Y * 0.203 - Z * 0.302;
    g = -X * 0.509 + Y * 1.412 + Z * 0.066;
    b = X * 0.026 - Y * 0.072 + Z * 0.962;
    r = r <= 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math.pow(r, (1.0 / 2.4)) - 0.055;
    g = g <= 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math.pow(g, (1.0 / 2.4)) - 0.055;
    b = b <= 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math.pow(b, (1.0 / 2.4)) - 0.055;
    maxValue = Math.max(r,g,b);
    r /= maxValue;
    g /= maxValue;
    b /= maxValue;
    r = r * 255;   if (r < 0) { r = 255 };
    g = g * 255;   if (g < 0) { g = 255 };
    b = b * 255;   if (b < 0) { b = 255 };
    r = Math.round(r).toString(16);
    g = Math.round(g).toString(16);
    b = Math.round(b).toString(16);
    if (r.length < 2)
        r="0"+r;        
    if (g.length < 2)
        g="0"+g;        
    if (b.length < 2)
        b="0"+r;        
    rgb = "#"+r+g+b;
    return rgb;             
}
alert(xyBriToRgb(0.5052,0.4151, 254));

我做了一个PHP版本:

function xyBriToRgb($x,$y,$bri)
{
    $z = 1.0 - $x - $y;
    $Y = $bri / 255.0;
    $X = ($Y / $y) * $x;
    $Z = ($Y / $y) * $z;
    $r = $X * 1.612 - $Y * 0.203 - $Z * 0.302;
    $g = ($X * -1) * 0.509 + $Y * 1.412 + $Z * 0.066;
    $b = $X * 0.026 - $Y * 0.072 + $Z * 0.962;
    $r = $r <= 0.0031308 ? 12.92 * $r : (1.0 + 0.055) * pow($r, (1.0 / 2.4)) - 0.055;
    $g = $g <= 0.0031308 ? 12.92 * $g : (1.0 + 0.055) * pow($g, (1.0 / 2.4)) - 0.055;
    $b = $b <= 0.0031308 ? 12.92 * $b : (1.0 + 0.055) * pow($b, (1.0 / 2.4)) - 0.055;
    $maxValue = max( $r , $g, $b );
    $r = $r / $maxValue;
    $g = $g / $maxValue;
    $b = $b / $maxValue;
    $r = $r * 255; if ($r < 0) $r = 255;
    $g = $g * 255; if ($g < 0) $g = 255;
    $b = $b * 255; if ($b < 0) $b = 255;
    $r = dechex(round($r));
    $g = dechex(round($g));
    $b = dechex(round($b));
    if (strlen($r) < 2)     $r = "0" + $r;
    if (strlen($g) < 2)     $g = "0" + $g;
    if (strlen($b) < 2)     $b = "0" + $b;
    return "#".$r.$g.$b;
}
print xyBriToRgb(0.5052,0.4151, 254);

祝大家编码愉快:-)

最后可能应该是

r = Math.round(r * 255); if (r < 0) { r = 0; }
g = Math.round(g * 255); if (g < 0) { g = 0; }
b = Math.round(b * 255); if (b < 0) { b = 0; }

如果rgb小于0,它不应该是0而不是255吗?我测试的颜色这样更有意义。不过谢谢你的公式!