# Gustavo Lopes' Blog

Commenting the most interesting Stack Overflow PHP questions

## Conversions RGB <-> HSV

This question inspired me to investigate the conversion between RGB and HSV. This manual page for imagecolorallocate is littered with functions like these, but I felt like writing my own.

These functions perform conversions from HSV to RGB and vice-versa, in the range [0,1]. The formula conversions were taken from the article Color Gamut Transform Pairs by Smith, A.R. et al.

function RGBtoHSV(array \$rgb) {
list(\$R,\$G,\$B) = \$rgb;
//1
\$V = max(\$R,\$G,\$B);
//2
\$X = min(\$R,\$G,\$B);
//3
\$S = (\$V-\$X)/\$V;
if (\$S == 0)
throw new Exception("Hue is undefined");
//4
\$r = (\$V-\$R)/(\$V-\$X);
\$g = (\$V-\$G)/(\$V-\$X);
\$b = (\$V-\$B)/(\$V-\$X);
//5
if (\$R == \$V)
\$H = \$G==\$X?(5+\$b):(1-\$g);
elseif (\$G == \$V)
\$H = \$B==\$X?(1+\$r):(3-\$b);
else
\$H = \$R==\$X?(3+\$g):(5-\$r);
//6
\$H /= 6;
return array(\$H, \$S, \$V);
}

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);
}
Sample with varying hue:
\$width = 401;
\$im = imagecreatetruecolor(\$width, 101);
imagecolorallocate(\$im,0,0,0); //background
\$saturation = .8;
\$value = .9;
imagesetthickness(\$im, 1);
for (\$i = 0; \$i < \$width; \$i++) {
\$hue = \$i / (\$width - 1);
list(\$r,\$g,\$b) = HSVtoRGB(array(\$hue, \$saturation, \$value));
\$c = imagecolorallocate(\$im,
(int) (\$r*255), (int) (\$g*255), (int) (\$b*255));
imageline(\$im, \$i, 0, \$i, 100, \$c) or die("oops");
}
imagepng(\$im);
Sample result:

Unregistered user Sunday, December 5, 2010 5:13:43 PM

Anonymous writes: Hum, there is an error with the function: original:#ff0000 2hsv:Array ( [0] => 360 [1] => 100 [2] => 100 ) hsv2rgb:#FF00FF Don't know why.

### Write a comment

New comments have been disabled for this post.

December 2013
M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31