开发者

PHP HSV to RGB formula comprehension

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;
  i开发者_如何转开发f ($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

PHP HSV to RGB formula comprehension


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


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


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


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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜