2011-01-24 3 views
0

색조 구성 요소를 사용하고 싶기 때문에 RGB32 값을 HSL로 변환하려고합니다.RGB에서 HSL로 색조 계산이 잘못되었습니다.

은 내가이 수업 만들기 위해 온라인으로 볼 몇 가지 예 사용하고 있습니다 : 제대로 작동하지 않는 것 같습니다 그러나

public class HSLColor 
    { 
     public Double Hue; 
     public Double Saturation; 
     public Double Luminosity; 

     public HSLColor(Double H, Double S, Double L) 
     { 
      Hue = H; 
      Saturation = S; 
      Luminosity = L; 
     } 

     public static HSLColor FromRGB(Color Clr) 
     { 
      return FromRGB(Clr.R, Clr.G, Clr.B); 
     } 

     public static HSLColor FromRGB(Byte R, Byte G, Byte B) 
     { 
      Double _R = (R/255d); 
      Double _G = (G/255d); 
      Double _B = (B/255d); 

      Double _Min = Math.Min(Math.Min(_R, _G), _B); 
      Double _Max = Math.Max(Math.Max(_R, _G), _B); 
      Double _Delta = _Max - _Min; 

      Double H = 0; 
      Double S = 0; 
      Double L = (float)((_Max + _Min)/2.0f); 

      if (_Delta != 0) 
      { 
       if (L < 0.5d) 
       { 
        S = (float)(_Delta/(_Max + _Min)); 
       } 
       else 
       { 
        S = (float)(_Delta/(2.0f - _Max - _Min)); 
       } 


       if (_R == _Max) 
       { 
        H = (_G - _B)/_Delta; 
       } 
       else if (_G == _Max) 
       { 
        H = 2f + (_B - _R)/_Delta; 
       } 
       else if (_B == _Max) 
       { 
        H = 4f + (_R - _G)/_Delta; 
       } 
      } 

      //Convert to degrees 
      H = H * 60d; 
      if (H < 0) H += 360; 
      //Convert to percent 
      S *= 100d; 
      L *= 100d; 

      return new HSLColor(H, S, L); 
     } 

     private Double Hue_2_RGB(Double v1, Double v2, Double vH) 
     { 
      if (vH < 0) vH += 1; 
      if (vH > 1) vH -= 1; 
      if ((6.0d * vH) < 1) return (v1 + (v2 - v1) * 6 * vH); 
      if ((2.0d * vH) < 1) return (v2); 
      if ((3.0d * vH) < 2) return (v1 + (v2 - v1) * ((2.0d/3.0d) - vH) * 6.0d); 
      return (v1); 
     } 

     public Color ToRGB() 
     { 
      Color Clr = new Color(); 
      Double var_1, var_2; 

      if (Saturation == 0) 
      { 
       Clr.R = (Byte)(Luminosity * 255); 
       Clr.G = (Byte)(Luminosity * 255); 
       Clr.B = (Byte)(Luminosity * 255); 
      } 
      else 
      { 
       if (Luminosity < 0.5) var_2 = Luminosity * (1 + Saturation); 
       else var_2 = (Luminosity + Saturation) - (Saturation * Luminosity); 

       var_1 = 2 * Luminosity - var_2; 

       Clr.R = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue + (1/3))); 
       Clr.G = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue)); 
       Clr.B = (Byte)(255 * Hue_2_RGB(var_1, var_2, Hue - (1/3))); 
      } 



      return Clr; 
     } 
    } 

내가 예를 들어 (R 0, G 255, B 193)의 입력 색상을 사용하는 경우

: Hue = 0 포토샵에서 정확한 RGB 값을 선택하면 Hue = 165 이 올바른 값입니다.

내가 색조가 문제가 무엇 240

0 ~ 360 또는 0에 이르기까지 값이되고 싶어 ..

참조 : EasyRGB RGB->HSL

+0

가능한 [HSL RGB로 다시 계산 문제]의 중복 (http://stackoverflow.com/questions/4793729/rgb-to-hsl-and-back-calculation-problems) – Mervin

답변

2

아래 인 오픈 소스 혼합물을 다시 RGB> 및 HSL 자랑하는 하나 개의 기능에 혼합 작업. 그것은 완벽하게 작동합니다. I 추가 한

<?php 
### RGB >> HSL 
function _color_rgb2hsl($rgb) { 
    $r = $rgb[0]; $g = $rgb[1]; $b = $rgb[2]; 
    $min = min($r, min($g, $b)); $max = max($r, max($g, $b)); 
    $delta = $max - $min; $l = ($min + $max)/2; $s = 0; 
    if ($l > 0 && $l < 1) { 
    $s = $delta/($l < 0.5 ? (2 * $l) : (2 - 2 * $l)); 
    } 
    $h = 0; 
    if ($delta > 0) { 
    if ($max == $r && $max != $g) $h += ($g - $b)/$delta; 
    if ($max == $g && $max != $b) $h += (2 + ($b - $r)/$delta); 
    if ($max == $b && $max != $r) $h += (4 + ($r - $g)/$delta); 
    $h /= 6; 
    } return array($h, $s, $l); 
} 

### HSL >> RGB 
function _color_hsl2rgb($hsl) { 
    $h = $hsl[0]; $s = $hsl[1]; $l = $hsl[2]; 
    $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s; 
    $m1 = $l * 2 - $m2; 
    return array(_color_hue2rgb($m1, $m2, $h + 0.33333), 
       _color_hue2rgb($m1, $m2, $h), 
       _color_hue2rgb($m1, $m2, $h - 0.33333)); 
} 

### Helper function for _color_hsl2rgb(). 
function _color_hue2rgb($m1, $m2, $h) { 
    $h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h); 
    if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6; 
    if ($h * 2 < 1) return $m2; 
    if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6; 
    return $m1; 
} 

### Convert a hex color into an RGB triplet. 
function _color_unpack($hex, $normalize = false) { 
    if (strlen($hex) == 4) { 
    $hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; 
    } $c = hexdec($hex); 
    for ($i = 16; $i >= 0; $i -= 8) { 
    $out[] = (($c >> $i) & 0xFF)/($normalize ? 255 : 1); 
    } return $out; 
} 

### Convert an RGB triplet to a hex color. 
function _color_pack($rgb, $normalize = false) { 
    foreach ($rgb as $k => $v) { 
    $out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8)); 
    }return '#'. str_pad(dechex($out), 6, 0, STR_PAD_LEFT); 
} 

    print "Hex: "; 

    $testhex = "#b7b700"; 
     print $testhex; 

    $testhex2rgb = _color_unpack($testhex,true); 
     print "<br />RGB: "; 

    var_dump($testhex2rgb); 
     print "<br />HSL color module: "; 

    $testrgb2hsl = _color_rgb2hsl($testhex2rgb); //Convert to HSL 

    var_dump($testrgb2hsl); 
     print "<br />RGB: "; 

    $testhsl2rgb = _color_hsl2rgb($testrgb2hsl); // And back to RGB  
    var_dump($testhsl2rgb); 
     print "<br />Hex: "; 

    $testrgb2hex = _color_pack($testhsl2rgb,true); 
    var_dump($testrgb2hex); 

?> 
4
R/255 

이 정수 0 점 또는 1 점을 의미합니다. 시도 :

(float)R/255 

및 기타 모든 경우. 상수

시도 : 드루팔 + 몇몇 다양한 프로그래머

(1/3) -> (1.0/3.0) 
+0

내 게시물에 대한 몇 가지 수정 사항, 색조 대신 색조 = 0,3333333333을 얻습니다. 165 – Mervin

+0

@Mervin이 수식을 받아서 종이에 계산합니다. 대답이 예상된다면 단계별로 디버그하고 코드 계산 결과가 종이와 다른지 확인하십시오. – Andrey

+0

@Mervin은 첫 번째 줄을 확인합니다. 당신은 0..255 범위에서 multuply 255로 그것을 마침내 원한다면 (범위 0..1에 맞는) 색상을 정규화하고 있습니다. – Andrey