Last active
November 16, 2023 20:49
-
-
Save zyphlar/55dea0fae7914ff8eb4a to your computer and use it in GitHub Desktop.
RGB and HSV conversion in PHP
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
<?php | |
// note: some of these are written with $this so they work inside classes. | |
// you could easily rewrite this to be a general function outside a class. | |
// sorry for the inconsistent tabs | |
// adapted from: http://www.actionscript.org/forums/showthread.php3?t=50746 via http://stackoverflow.com/questions/1773698/rgb-to-hsv-in-php | |
class MyClass | |
{ | |
// usage: $this->hexColorMod("#aa00ff", -0.2); // darker by 20% | |
// returns: #8700cc | |
private function hexColorMod($hex, $diff) { | |
$rgbhex = str_split(trim($hex, '# '), 2); | |
$rgbdec = array_map("hexdec", $rgbhex); | |
$hsv = $this->RGB_TO_HSV($rgbdec[0], $rgbdec[1], $rgbdec[2]); | |
$hsv['V'] = max(0, min(1, $hsv['V'] + $diff)); | |
$rgbdark = $this->HSV_TO_RGB($hsv['H'], $hsv['S'], $hsv['V']); | |
$output = array_map("dechex", $rgbdark); | |
$output = array_map(array($this,"zeropad2"), $output); // gotta zero-pad single-digit hex | |
return '#'.implode($output); | |
} | |
private function zeropad2($num) | |
{ | |
$limit = 2; | |
return (strlen($num) >= $limit) ? $num : $this->zeropad2("0" . $num); | |
} | |
private function RGB_TO_HSV ($R, $G, $B) // RGB Values:Number 0-255 | |
{ // HSV Results:Number 0-1 | |
$HSL = array(); | |
$var_R = ($R / 255); | |
$var_G = ($G / 255); | |
$var_B = ($B / 255); | |
$var_Min = min($var_R, $var_G, $var_B); | |
$var_Max = max($var_R, $var_G, $var_B); | |
$del_Max = $var_Max - $var_Min; | |
$V = $var_Max; | |
if ($del_Max == 0) | |
{ | |
$H = 0; | |
$S = 0; | |
} | |
else | |
{ | |
$S = $del_Max / $var_Max; | |
$del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; | |
$del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; | |
$del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max; | |
if ($var_R == $var_Max) $H = $del_B - $del_G; | |
else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B; | |
else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R; | |
if ($H<0) $H++; | |
if ($H>1) $H--; | |
} | |
$HSL['H'] = $H; | |
$HSL['S'] = $S; | |
$HSL['V'] = $V; | |
return $HSL; | |
} | |
function HSV_TO_RGB ($H, $S, $V) // HSV Values:Number 0-1 | |
{ // RGB Results:Number 0-255 | |
$RGB = array(); | |
if($S == 0) | |
{ | |
$R = $G = $B = $V * 255; | |
} | |
else | |
{ | |
$var_H = $H * 6; | |
$var_i = floor( $var_H ); | |
$var_1 = $V * ( 1 - $S ); | |
$var_2 = $V * ( 1 - $S * ( $var_H - $var_i ) ); | |
$var_3 = $V * ( 1 - $S * (1 - ( $var_H - $var_i ) ) ); | |
if ($var_i == 0) { $var_R = $V ; $var_G = $var_3 ; $var_B = $var_1 ; } | |
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $V ; $var_B = $var_1 ; } | |
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $V ; $var_B = $var_3 ; } | |
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $V ; } | |
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $V ; } | |
else { $var_R = $V ; $var_G = $var_1 ; $var_B = $var_2 ; } | |
$R = $var_R * 255; | |
$G = $var_G * 255; | |
$B = $var_B * 255; | |
} | |
$RGB['R'] = $R; | |
$RGB['G'] = $G; | |
$RGB['B'] = $B; | |
return $RGB; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the class and code. This works only to darken a color.
I modified the following part, so you can adjust the new color to be lighter or darker.
change #17
$hsv['V'] = $hsv['V'] + $diff;
top:
$hsv['V'] = max(0, min(1, $hsv['V'] + $diff));