PHP HSV to RGB formula comprehension

偶尔善良 提交于 2019-11-26 14:21:59

问题


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:


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



回答6:


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.



来源:https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!