PHP HSV to RGB formula comprehension
This is for the the HSV values in the range [0,1]
(and giving RGB values in the range [0,1]
, instead of {0, 1, ..., 255}
:
function HSVtoRGB(array $hsv) {
list($H,$S,$V) = $hsv;
//1
$H *= 6;
//2
$I = floor($H);
$F = $H - $I;
//3
$M = $V * (1 - $S);
$N = $V * (1 - $S * $F);
$K = $V * (1 - $S * (1 - $F));
//4
switch ($I) {
case 0:
list($R,$G,$B) = array($V,$K,$M);
break;
case 1:
list($R,$G,$B) = array($N,$V,$M);
break;
case 2:
list($R,$G,$B) = array($M,$V,$K);
break;
case 3:
list($R,$G,$B) = array($M,$N,$V);
break;
case 4:
list($R,$G,$B) = array($K,$M,$V);
break;
case 5:
case 6: //for when $H=1 is given
list($R,$G,$B) = array($V,$M,$N);
break;
}
return array($R, $G, $B);
}
Found this post too late, my alternate take on it:
hsv2rgb function PHP
hue: 0-360, sat: 0-100, val: 0-100
function hsv2rgb($hue,$sat,$val) {;
$rgb = array(0,0,0);
//calc rgb for 100% SV, go +1 for BR-range
for($i=0;$i<4;$i++) {
if (abs($hue - $i*120)<120) {
$distance = max(60,abs($hue - $i*120));
$rgb[$i % 3] = 1 - (($distance-60) / 60);
}
}
//desaturate by increasing lower levels
$max = max($rgb);
$factor = 255 * ($val/100);
for($i=0;$i<3;$i++) {
//use distance between 0 and max (1) and multiply with value
$rgb[$i] = round(($rgb[$i] + ($max - $rgb[$i]) * (1 - $sat/100)) * $factor);
}
$rgb['html'] = sprintf('#%02X%02X%02X', $rgb[0], $rgb[1], $rgb[2]);
return $rgb;
}
Translation of rolls answer for HSL from C to PHP
function ColorHSLToRGB($h, $s, $l){
$r = $l;
$g = $l;
$b = $l;
$v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
if ($v > 0){
$m;
$sv;
$sextant;
$fract;
$vsf;
$mid1;
$mid2;
$m = $l + $l - $v;
$sv = ($v - $m ) / $v;
$h *= 6.0;
$sextant = floor($h);
$fract = $h - $sextant;
$vsf = $v * $sv * $fract;
$mid1 = $m + $vsf;
$mid2 = $v - $vsf;
switch ($sextant)
{
case 0:
$r = $v;
$g = $mid1;
$b = $m;
break;
case 1:
$r = $mid2;
$g = $v;
$b = $m;
break;
case 2:
$r = $m;
$g = $v;
$b = $mid1;
break;
case 3:
$r = $m;
$g = $mid2;
$b = $v;
break;
case 4:
$r = $mid1;
$g = $m;
$b = $v;
break;
case 5:
$r = $v;
$g = $m;
$b = $mid2;
break;
}
}
return array('r' => $r * 255.0, 'g' => $g * 255.0, 'b' => $b * 255.0);
}
private class HSLPixel{
double hue;
double saturation;
double lightness;
.... your code
}
public Color HSLToRGB(HSLPixel pixel){
double v;
double r,g,b;
double l = pixel.lightness;
double h = pixel.hue;
double s = pixel.saturation;
r = l; // default to gray
g = l;
b = l;
v = (l <= 0.5) ? (l * (1.0 + s)) : (l + s - l * s);
if (v > 0){
double m;
double sv;
int sextant;
double fract, vsf, mid1, mid2;
m = l + l - v;
sv = (v - m ) / v;
h *= 6.0;
sextant = (int)h;
fract = h - sextant;
vsf = v * sv * fract;
mid1 = m + vsf;
mid2 = v - vsf;
switch (sextant)
{
case 0:
r = v;
g = mid1;
b = m;
break;
case 1:
r = mid2;
g = v;
b = m;
break;
case 2:
r = m;
g = v;
b = mid1;
break;
case 3:
r = m;
g = mid2;
b = v;
break;
case 4:
r = mid1;
g = m;
b = v;
break;
case 5:
r = v;
g = m;
b = mid2;
break;
}
}
Color rgb = new Color((int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
return rgb;
}