Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RGB to HSV in PHP

In PHP, what is the most straightforward way to convert a RGB triplet to HSV values?

like image 729
Alix Axel Avatar asked Nov 20 '09 22:11

Alix Axel


People also ask

How do you convert RGB value to HSV?

HSV = rgb2hsv( RGB ) converts the red, green, and blue values of an RGB image to hue, saturation, and value (HSV) values of an HSV image. hsvmap = rgb2hsv( rgbmap ) converts an RGB colormap to an HSV colormap.

How do you convert RGB to HSV manually?

Converting RGB to HSVH = 360 - cos-1[ (R - ½G - ½B)/√R² + G² + B² - RG - RB - GB ] if B > G. Inverse cosine is calculated in degrees.

What is BGR to HSV?

While in BGR, an image is treated as an additive result of three base colors (blue, green and red), HSV stands for Hue, Saturation and Value (Brightness). We can say that HSV is a rearrangement of RGB in a cylindrical shape. The HSV ranges are: 0 > H > 360 ⇒ OpenCV range = H/2 (0 > H > 180)


3 Answers

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

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

Heavily documented for learning 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's arc (60 degrees) to obtain the angle in degrees.     $computedH = 60 * $h;      return array($computedH, $computedS, $computedV); }  ?> 
like image 129
Unsigned Avatar answered Sep 22 '22 05:09

Unsigned


<?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;
}
like image 28
Jacob Avatar answered Sep 22 '22 05:09

Jacob


Thoroughly tested and compressed, this is the function I'm going to stick with for converting 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 using 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
)
like image 25
ashleedawg Avatar answered Sep 23 '22 05:09

ashleedawg