将RGB颜色转换为XY

时间:2019-02-13 06:34:43

标签: javascript colors processing philips-hue ruckus-api

我已经使用RUCKUS API更改灯的颜色,并且需要将颜色从RGB转换为XY才能调用API。

我已经尝试过此代码:

1)从颜色对象中获取RGB值,并将其转换为0到1之间的值

 function rgb_to_cie(red, green, blue)
    {
        //Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device
        var red     = (red > 0.04045) ? Math.pow((red + 0.055) / (1.0 + 0.055), 2.4) : (red / 12.92);
        var green   = (green > 0.04045) ? Math.pow((green + 0.055) / (1.0 + 0.055), 2.4) : (green / 12.92);
        var blue    = (blue > 0.04045) ? Math.pow((blue + 0.055) / (1.0 + 0.055), 2.4) : (blue / 12.92); 

        //RGB values to XYZ using the Wide RGB D65 conversion formula
        var X       = red * 0.664511 + green * 0.154324 + blue * 0.162028;
        var Y       = red * 0.283881 + green * 0.668433 + blue * 0.047685;
        var Z       = red * 0.000088 + green * 0.072310 + blue * 0.986039;

        //Calculate the xy values from the XYZ values
        var x       = (X / (X + Y + Z)).toFixed(4);
        var y       = (Y / (X + Y + Z)).toFixed(4);

        if (isNaN(x))
            x = 0;
        if (isNaN(y))
            y = 0;   
        return [x, y];
    }

但是它没有提供适当的解决方案。

因此,如果我通过 r:182 g:255 B:65 ,那么我得到 x为22932 y为35249 (根据API的文档。)

我该怎么做?

2 个答案:

答案 0 :(得分:0)

几乎没有错误:

首先:您正在使用常规转换公式,其中红色,绿色和蓝色的范围应在0.0到1.0之间。因此,您可能需要将这些值除以255。

第二:您正在应用伽玛。要转换为X,Y,Z,您需要线性值。通常,我们具有经过伽马校正的RGB(例如像素值)。因此,您正在过度校正。相反,您应该应用gamma的逆,以便获得线性R,G,B,以便可以进行线性变换以获得X,Y,Z。

第三:您要返回x,y,而不是X,Y,作为您的问题(和评论)。另一方面,您确定需要X,Y吗? x,y通常用于“颜色”。我希望得到x,y + Y(或某些亮度参数)。

可能您应该缩小这些值。如您所见,通常范围是0到1,或0到100(过去),或0到255,0到65535。没有标准:这些只是没有单位的数字。 [与计算机屏幕相反,Phillips Hue应该知道这是最大亮度,但是..这是个例外]。

答案 1 :(得分:0)

我找到了解决方案,如果您正在寻求帮助,请在此处附上答案,

let red = 100
let green = 100
let blue = 100

let redC =  (red / 255)
let greenC = (green / 255)
let blueC = (blue / 255)
console.log(redC, greenC , blueC)


let redN = (redC > 0.04045) ? Math.pow((redC + 0.055) / (1.0 + 0.055), 2.4): (redC / 12.92)
let greenN = (greenC > 0.04045) ? Math.pow((greenC + 0.055) / (1.0 + 0.055), 2.4) : (greenC / 12.92)
let blueN = (blueC > 0.04045) ? Math.pow((blueC + 0.055) / (1.0 + 0.055), 2.4) : (blueC / 12.92)
console.log(redN, greenN, blueN)

let X = redN * 0.664511 + greenN * 0.154324 + blueN * 0.162028;

let Y = redN * 0.283881 + greenN * 0.668433 + blueN * 0.047685;

let Z = redN * 0.000088 + greenN * 0.072310 + blueN * 0.986039;
console.log(X, Y, Z)

let x = X / (X + Y + Z);

let y = Y / (X + Y + Z);

X = x * 65536 
Y = y * 65536