PHP HSV to RGB formula comprehension

2019-01-09 06:44发布

问题:

I can convert RGB values to HSV with the following code...

 $r = $r/255;
 $g = $g/255;
 $b = $b/255;

 $h = 0;
 $s = 0;
 $v = 0;

 $min = min(min($r, $g),$b);
 $max = max(max($r, $g),$b);

 $r = $max-$min;
 $v = $max;


 if($r == 0){
  $h = 0;
  $s = 0;
 }
 else {
  $s = $r / $max;

  $hr = ((($max - $r) / 6) + ($r / 2)) / $r;
  $hg = ((($max - $g) / 6) + ($r / 2)) / $r;
  $hb = ((($max - $b) / 6) + ($r / 2)) / $r;

  if ($r == $max) $h = $hb - $hg;
  else if($g == $max) $h = (1/3) + $hr - $hb;
  else if ($b == $max) $h = (2/3) + $hg - $hr;

  if ($h < 0)$h += 1;
  if ($h > 1)$h -= 1;
 }

But how do you convert HSV to RGB in PHP???

The following is on wikipedia but I don't understand it,

I'm guessing it's pretty obvious

回答1:

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);
}


回答2:

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);
}


回答3:

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;
    }


回答4:

ColorJizz allows you to convert from/to many formats. There is a PHP version too.



回答5:

of course you can, just change the function definitions to php style, change all the variables etc but keep the core code the same, shouldn't take you more than 30 minutes to do that and test it.



回答6:

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;
  }


标签: php colors rgb hsv