• PHP Help
  • PHP function to convert Hex to HSL (Not HSL to Hex)

I am trying to convert colors from Hex to HSL (Not HSL to Hex). I am using a PHP function for this purpose. But It's not working properly for some colors. For example for #e04c4c the HSL should be (0, 70%, 59%) which it isn't the case with the function.

function hexToHsl($hex) {
    $red = hexdec(substr($hex, 0, 2)) / 255;
    $green = hexdec(substr($hex, 2, 2)) / 255;
    $blue = hexdec(substr($hex, 4, 2)) / 255;

    $cmin = min($red, $green, $blue);
    $cmax = max($red, $green, $blue);
    $delta = $cmax - $cmin;

    if ($delta === 0) {
        $hue = 0;
    } elseif ($cmax === $red) {
        $hue = (($green - $blue) / $delta) % 6;
    } elseif ($cmax === $green) {
        $hue = ($blue - $red) / $delta + 2;
    } else {
        $hue = ($red - $green) / $delta + 4;
    }

    $hue = round($hue * 60);
    if ($hue < 0) {
        $hue += 360;
    }

    $lightness = (($cmax + $cmin) / 2) * 100;
    $saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1))) * 100;
    if ($saturation < 0) {
        $saturation += 100;
    }

    $lightness = round($lightness);
    $saturation = round($saturation);

    //return "hsl(${hue}, ${saturation}%, ${lightness}%)";
    return array($hue, $saturation, $lightness);
}

This is how I used it:

$templatePrimaryColor = '#e04c4c';

$templatePrimaryColor = str_replace("#", "",$templatePrimaryColor);

list($h,$s,$l) = hexToHsl($templatePrimaryColor);

$primaryColor = "hsl(${h}, ${s}%, ${l}%)";

This is the output:


echo '<pre>',print_r(hexToHsl($templatePrimaryColor)).'</pre>';

Array
(
    [0] => 0
    [1] => 99
    [2] => 59
)
1

Does anyone know what is the problem there?

Thank you.

    It doesn't matter whether the function converts to RGB or hex because converting between those two is trivial. The inputs are HSL values for CSS (Hue: 0–360, Saturation: 0–100, Lightness: 0–100)

      $lightness = (($cmax + $cmin) / 2) * 100;
          $saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1))) * 100;
      

      You jump the gun a bit multiplying by 100 when you calculate $lightness here — you still need the [0,1] value on the next line when you calculate the saturation.

      I'd suggest leaving off scaling for different units (percentages here) until the round step. I.e.,

          $lightness = (($cmax + $cmin) / 2) ;
          $saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1)));
      
      if ($saturation < 0) {
          $saturation += 1;
      }
      
      $lightness = round($lightness*100);
      $saturation = round($saturation*100);
      
        7 months later

        Thanks for share this function!
        It's working!
        function thegiraffe_hex_to_hsl($hex) {
        $red = hexdec(substr($hex, 0, 2)) / 255;
        $green = hexdec(substr($hex, 2, 2)) / 255;
        $blue = hexdec(substr($hex, 4, 2)) / 255;

        $cmin = min($red, $green, $blue);
        $cmax = max($red, $green, $blue);
        $delta = $cmax - $cmin;
        
        if ($delta == 0) {
        	$hue = 0;
        } elseif ($cmax === $red) {
        	$hue = (($green - $blue) / $delta);
        } elseif ($cmax === $green) {
        	$hue = ($blue - $red) / $delta + 2;
        } else {
        	$hue = ($red - $green) / $delta + 4;
        }
        
        $hue = round($hue * 60);
        if ($hue < 0) {
        	$hue += 360;
        }
        
        $lightness = (($cmax + $cmin) / 2);
        $saturation = $delta === 0 ? 0 : ($delta / (1 - abs(2 * $lightness - 1)));
        if ($saturation < 0) {
        	$saturation += 1;
        }
        
        $lightness = round($lightness*100);
        $saturation = round($saturation*100);
        
        // return "hsl(${hue}, ${saturation}%, ${lightness}%)";
        
        return array($hue, $saturation, $lightness);

        }

          Write a Reply...