Last active
June 12, 2021 06:49
-
-
Save brandonheyer/5254516 to your computer and use it in GitHub Desktop.
PHP snippet to convert RGB to HSL and HSL to RGB.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
function rgbToHsl( $r, $g, $b ) { | |
$oldR = $r; | |
$oldG = $g; | |
$oldB = $b; | |
$r /= 255; | |
$g /= 255; | |
$b /= 255; | |
$max = max( $r, $g, $b ); | |
$min = min( $r, $g, $b ); | |
$h; | |
$s; | |
$l = ( $max + $min ) / 2; | |
$d = $max - $min; | |
if( $d == 0 ){ | |
$h = $s = 0; // achromatic | |
} else { | |
$s = $d / ( 1 - abs( 2 * $l - 1 ) ); | |
switch( $max ){ | |
case $r: | |
$h = 60 * fmod( ( ( $g - $b ) / $d ), 6 ); | |
if ($b > $g) { | |
$h += 360; | |
} | |
break; | |
case $g: | |
$h = 60 * ( ( $b - $r ) / $d + 2 ); | |
break; | |
case $b: | |
$h = 60 * ( ( $r - $g ) / $d + 4 ); | |
break; | |
} | |
} | |
return array( round( $h, 2 ), round( $s, 2 ), round( $l, 2 ) ); | |
} | |
function hslToRgb( $h, $s, $l ){ | |
$r; | |
$g; | |
$b; | |
$c = ( 1 - abs( 2 * $l - 1 ) ) * $s; | |
$x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) ); | |
$m = $l - ( $c / 2 ); | |
if ( $h < 60 ) { | |
$r = $c; | |
$g = $x; | |
$b = 0; | |
} else if ( $h < 120 ) { | |
$r = $x; | |
$g = $c; | |
$b = 0; | |
} else if ( $h < 180 ) { | |
$r = 0; | |
$g = $c; | |
$b = $x; | |
} else if ( $h < 240 ) { | |
$r = 0; | |
$g = $x; | |
$b = $c; | |
} else if ( $h < 300 ) { | |
$r = $x; | |
$g = 0; | |
$b = $c; | |
} else { | |
$r = $c; | |
$g = 0; | |
$b = $x; | |
} | |
$r = ( $r + $m ) * 255; | |
$g = ( $g + $m ) * 255; | |
$b = ( $b + $m ) * 255; | |
return array( floor( $r ), floor( $g ), floor( $b ) ); | |
} | |
?> |
Hey, I successfully implemented this code for RGB hex (wasn't too hard) and I'm happy you shared it! Wanted to add discoveries I made for that use case, which is that if you slightly alter the final return statements, re-conversion can be perfect 1-to-1.
rgbToHsl
's precision on round
should be upped from 2 to 3, and hslToRgb
's operation changed from floor
to round
.
Before I changed this I'd sometimes get small differences when converting RGB -> HSL -> RGB. I'm no expert on how performant this is, but I thought it'd be helpful to know. Cheers!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that with the functions above, hslToRgb expects Saturation and Lightness in the range 0 to 1, and rgbToHsl returns the values the same way. Hue is 0 to 360. R/G/B are 0-255.
The first line 3 lines within rgbToHsl ("old" values) are not needed.
Below are "compressed" versions of both. (These ones take/give S and L in the 0 to 100 range but are otherwise the same.)