RGB to HSV in PHP

In PHP, what is the easiest way to convert RGB triplets to HSV values?

+20
php colors image rgb hsv
Nov 20 '09 at 22:47
source share
5 answers
<?php 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; } 
+16
Nov 20 '09 at 22:59
source share

Here is a simple and straightforward method that returns HSV values ​​as degrees and percentages, which uses Photoshop color picker.

Please note that the return values ​​are not rounded, you can do it yourself if necessary. Keep in mind that H(360) == H(0) , so H values ​​of 359.5 and greater should round to 0

Hardly documented for educational purposes.

 /** * Licensed under the terms of the BSD License. * (Basically, this means you can do whatever you like with it, * but if you just copy and paste my code into your app, you * should give me a shout-out/credit :) */ <?php function RGBtoHSV($R, $G, $B) // RGB values: 0-255, 0-255, 0-255 { // HSV values: 0-360, 0-100, 0-100 // Convert the RGB byte-values to percentages $R = ($R / 255); $G = ($G / 255); $B = ($B / 255); // Calculate a few basic values, the maximum value of R,G,B, the // minimum value, and the difference of the two (chroma). $maxRGB = max($R, $G, $B); $minRGB = min($R, $G, $B); $chroma = $maxRGB - $minRGB; // Value (also called Brightness) is the easiest component to calculate, // and is simply the highest value among the R,G,B components. // We multiply by 100 to turn the decimal into a readable percent value. $computedV = 100 * $maxRGB; // Special case if hueless (equal parts RGB make black, white, or grays) // Note that Hue is technically undefined when chroma is zero, as // attempting to calculate it would cause division by zero (see // below), so most applications simply substitute a Hue of zero. // Saturation will always be zero in this case, see below for details. if ($chroma == 0) return array(0, 0, $computedV); // Saturation is also simple to compute, and is simply the chroma // over the Value (or Brightness) // Again, multiplied by 100 to get a percentage. $computedS = 100 * ($chroma / $maxRGB); // Calculate Hue component // Hue is calculated on the "chromacity plane", which is represented // as a 2D hexagon, divided into six 60-degree sectors. We calculate // the bisecting angle as a value 0 <= x < 6, that represents which // portion of which sector the line falls on. if ($R == $minRGB) $h = 3 - (($G - $B) / $chroma); elseif ($B == $minRGB) $h = 1 - (($R - $G) / $chroma); else // $G == $minRGB $h = 5 - (($B - $R) / $chroma); // After we have the sector position, we multiply it by the size of // each sector arc (60 degrees) to obtain the angle in degrees. $computedH = 60 * $h; return array($computedH, $computedS, $computedV); } ?> 
+32
Dec 14 '12 at 23:59
source share

Thoroughly tested and compressed, I'm going to stick with this function to convert RGB to HSV :

 function RGBtoHSV($r,$g,$b) { $r=($r/255); $g=($g/255); $b=($b/255); $maxRGB=max($r,$g,$b); $minRGB=min($r,$g,$b); $chroma=$maxRGB-$minRGB; if($chroma==0) return array('h'=>0,'s'=>0,'v'=>$maxRGB); if($r==$minRGB)$h=3-(($g-$b)/$chroma); elseif($b==$minRGB)$h=1-(($r-$g)/$chroma); else $h=5-(($b-$r)/$chroma); return array('h'=>60*$h,'s'=>$chroma/$maxRGB,'v'=>$maxRGB); } 



Example:

Example of using the color " DarkSalmon ":

 echo '<pre><code>'. print_r( RGBtoHSV(233,150,122), true ) .'</code></pre>'; 

... returns:

 Array ( [h] => 15.135135135135 [s] => 0.47639484978541 [v] => 0.91372549019608 ) 
0
May 15 '19 at 3:14
source share

I made it like this

 function convertRgbToHsv($rgb) { $r = (int)substr($rgb, 0, 3) / 255; $g = (int)substr($rgb, 3, 3) / 255; $b = (int)substr($rgb, 6, 3) / 255; $max = max($r, $g, $b); $min = min($r, $g, $b); $delta = $max - $min; if (!$delta) { $h = 0; } else if ($r === $max) { $h = 60 * ((($g - $b) / $delta) % 6); } else if ($g === $max) { $h = 60 * ((($b - $r) / $delta) + 2); } else { $h = 60 * ((($r - $g) / $delta) + 4); } $s = !!$max ? $delta / $max : 0; $v = $max; $hsv = array("h" => $h, "s" => $s, "v" => $v); return $hsv; } 

Link to reference material here

0
Sep 09 '19 at 2:46
source share

Here is my rotation on it, along with the unit test. Since the values ​​of S and V are percentages, this code returns them as integers (0, 100), and not (0, 1) - an example, 75 instead of 0.75 .

 final class MathService { /** * Converts an RGB point into HSV * * @param int $r * @param int $g * @param int $b * @return array */ public function rgbToHsv(int $r, int $g, int $b): array { $rPrime = $r / 255; $gPrime = $g / 255; $bPrime = $b / 255; $max = max([$rPrime, $gPrime, $bPrime]); $min = min([$rPrime, $gPrime, $bPrime]); $delta = $max - $min; // Calculate H if ($delta == 0) { $h = 0; } else { if ($max === $rPrime) { $h = 60 * ((($gPrime - $bPrime) / $delta) % 6); } if ($max === $gPrime) { $h = 60 * ((($bPrime - $rPrime) / $delta) + 2); } if ($max === $bPrime) { $h = 60 * ((($rPrime - $gPrime) / $delta) + 4); } } // Calculate S if ($max == 0) { $s = 0; } else { $s = $delta / $max; } // Calculate V $v = $max; return [$h, (int)($s * 100), (int)($v * 100)]; } } 

PHPUnit test case with PHP 7.2

 /** * @test */ public function rgbToHsv_ComputesCorrectValues(): void { $service = new MathService(); $samples = [ // [R, G, B, H, S, V] [0, 0, 0, 0, 0, 0], [255, 255, 255, 0, 0, 100], [255, 0, 0, 0, 100, 100], [0, 255, 0, 120, 100, 100], [0, 0, 255, 240, 100, 100], [255, 255, 0, 60, 100, 100], [0, 255, 255, 180, 100, 100], [255, 0, 255, 300, 100, 100], [192, 192, 192, 0, 0, 75], [128, 128, 128, 0, 0, 50], [128, 0, 0, 0, 100, 50], [128, 128, 0, 60, 100, 50], [0, 128, 0, 120, 100, 50], [128, 0, 128, 300, 100, 50], [0, 128, 128, 180, 100, 50], [0, 0, 128, 240, 100, 50], ]; foreach ($samples as $sample) { list($r, $g, $b) = array_slice($sample, 0, 3); $expected = array_slice($sample, 3); $hsv = $service->rgbToHsv($r, $g, $b); list($h, $s, $v) = $hsv; self::assertEquals($expected, $hsv, "Error converting ({$r}, ${g}, ${b}). Got ({$h}, {$s}, {$v})"); } } 
-one
Mar 25 '18 at 4:01
source share



All Articles