Cowlby
Cowlby

Reputation: 651

Convert Philips Hue XY values to HEX

The Philips Hue API returns an xy value in certain cases for the color value of the blub. How can I convert this to a HEX string? I've tried various formulas I found online but none of them work on all of the colors from the bulb.

I took a look at the guides suggested below and tried to implement in PHP as follows:

list($x, $y) = $light['state']['xy'];
$z = 1.0 - $x - $y;
$Y = $light['state']['bri'] / 255.0; // The given brightness value
$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) * 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;

I set one of my lights to the red at the bottom left of the color picker in the Hue app and set brightness to max. Here are the resulting values:

// Read from bulb
x = 0.6472
y = 0.3302
bri = 254

// XYZ calculations
X = 1.952
Y = 0.996
Z = 0.068

// RGB calculations
r = 1.594 // Out-of-range > 1
g = 0.677
b = 0.233

As you can see, the r value generated is out of range as it is higher than 1. What am I missing in my equations?

Upvotes: 4

Views: 9793

Answers (2)

PhilipsHueDev
PhilipsHueDev

Reputation: 84

The Philips Hue iOS SDK Application Design Note for RGB to xy and vice versa will help you solve this: https://github.com/PhilipsHue/PhilipsHueSDKiOS/tree/master/ApplicationDesignNotes. Also note that I will be updating that note shortly to include Objective-C code for the functions. Once you have converted the xy to RGB, you can translate the values to HEX.

Upvotes: 3

Tobias M&#252;ller
Tobias M&#252;ller

Reputation: 605

As you can see, the r value generated is out of range as it is higher than 1. What am I missing in my equations?

The xy values returned by the Philips hue API are in CIE 1931 color space. This color space indices all colors visible by the human eye. As this color space is larger that what your device can display, not all colors are mapable to colors within the device's color space.

For example if you assume the device's color capabilities as sRGB then all the colors outside the gamut will result in a negative value for R, G and/or B. The solve this you must map these colors to a displayable color within the gamut. The easiest option is to set all value to 0 if they are negative.

Values greater than 1 can also appear. The easiest solution for this problem is to rescale all color values by the same factor so that everything is smaller than 1. A simple approach would be something like

$maxValue = max($r,$g,$b);
$r /= $maxValue;
$g /= $maxValue;
$b /= $maxValue;

Upvotes: 7

Related Questions