1

When converting from HSL to RGB the math involved seems relatively simple, especially when converting grayscale as the RGB values are the lightness multiplied by 255.

However take this hex #eeeeee. It's RGB value is rgb(238,238,238) and it's HSL representation is hsl(0.00, 0.00, 0.93).

Every reference to a conversion I have found simply does this:

// Hard coded values for brevity
$hue = 0.00;
$saturation = 0.00;
$lightness = 0.00;

if ($saturation == 0)
{
    $red = $green = $blue = $lightness;
}
else
{
    // Or run the math
}

$rgb = [round($red * 255), round($green * 255), round($blue * 255)];

In the case of #eeeeee we know the following

$red = $green = $blue = 0.93;

And all the RGB values === 238.

The math in all the conversions I have seen do not stack.

0.93 * 255 = 237.15

(as a note rgb(237,237,237) produces hex #ededed)

After rounding we are left with 237. So we change the result to use ciel. Well this works for this case but breaks a lot of other conversions.

There is a step in this conversion that I'm missing (and so it seems is the rest of the world). Does anyone have any idea how to accurately calculate the RGB values from HSL?

David Barker
  • 14,484
  • 3
  • 48
  • 77
  • 238/255 is not 0.93, it is 0.93333.... Thus it's not surprising that you don't get 238 when you multiply 255 and 0.93. Looking at it from a different angle, there are 256 grayscale values from #000000 to #ffffff, but only 100 lightness values from 0.00 to 1.00, so you can't possibly have a one-to-one mapping from RGB to HSL and back when using a two-digit decimal. – Lithis Jul 24 '15 at 16:57
  • @Lithis I recognise this. HSL has at most 100 shades of true grey versus the 256 available with hex codes. The question is focused on **how** can I convert an RGB value that **DOES** have an HSL representation and a commonly used hex code to RGB accurately. Though the fact I'm not working on doubles with any more than 3 decimal places may have a lot to do with this. Thanks for the thoughts. – David Barker Jul 24 '15 at 17:00

1 Answers1

2

Based on the comment from @Lithis it became immediately clear that the problem is with the accuracy of HSL values. As was pointed out in the comment:

238 / 255 = 0.9333333 recurring

Increasing the floating point accuracy within the conversion creates the hex codes expected. So instead of:

0.93 * 255 = 237.15

We work with

0.93333 * 255 = 237.99915

Which is far more acceptable a result than 237.15

David Barker
  • 14,484
  • 3
  • 48
  • 77