ФлеймФорумПрограммирование

Конвертация цвета из HSB в RGB

#0
23:10, 16 июля 2011

Нужно определять значения красного, зелёного и синего в системе RGB по значению параметров в системе HSB.
Написал код для случая, когда Saturation и Brightness равны 255, а меняется только Hue. Но преследует ощущение, что изобретаю велосипед. Наверняка есть уже готовые формулы для перевода цветов в RGB.

#1
23:17, 16 июля 2011

петрушка
> а меняется только Hue

хыхы, слышь баклан, он сказал слово Hue гыгыгы

(почему не в основном разделе?)

#2
23:18, 16 июля 2011

Посмотри в как сделано в GLScene

// GetHSVA
//
function TGLColor.GetHSVA : TVector;
var
   delta, min : Single;
const
   H = 0;
   S = 1;
   V = 2;
begin
   min:=MinFloat(PFloatVector(@FColor), 3);
   Result[V]:=MaxFloat(PFloatVector(@FColor), 3);
   delta:=Result[V]-min;

  // saturation is zero if R, G & B are zero
  // hue undefined (zero) if saturation is zero or color is gray (delta=zero)
   if (Result[V]=0) or (delta=0) then begin
      Result[S]:=0;
      Result[H]:=0;
   end else begin
      Result[S]:=delta/Result[V];
      if Red=Result[V] then
         // between yellow and magenta
         Result[H]:=60*(Green-Blue)/delta
      else if Green=Result[V] then
         // between cyan and yellow
         Result[H]:=120+60*(Blue-Red)/delta
      else // between magenta and cyan
         Result[H]:=240+60*(Red-Green)/delta;
      if Result[H]<0 then  // normalize H
         Result[H]:=Result[H]+360;
   end;
   Result[3]:=Alpha;
end;

// SetHSVA
//
procedure TGLColor.SetHSVA(const hsva : TVector);
var
   f, hTemp, p, q, t : Single;
const
   H = 0;
   S = 1;
   V = 2;
begin
   if hsva[S]=0 then begin
      // gray (ignore hue)
      FColor[0]:=hsva[V];
      FColor[1]:=hsva[V];
      FColor[2]:=hsva[V];
   end else begin
      hTemp:=hsva[H]*(1/60);
      f:=Frac(hTemp);

      p:=hsva[V]*(1-hsva[S]);
      q:=hsva[V]*(1-(hsva[S]*f));
      t:=hsva[V]*(1-(hsva[S]*(1-f)));

      case Trunc(hTemp) mod 6 of
         0 : begin
            FColor[0]:=hsva[V];
            FColor[1]:=t;
            FColor[2]:=p;
         end;
         1 : begin
            FColor[0]:=q;
            FColor[1]:=hsva[V];
            FColor[2]:=p;
         end;
         2 : begin
            FColor[0]:=p;
            FColor[1]:=hsva[V];
            FColor[2]:=t;
         end;
         3 : begin
            FColor[0]:=p;
            FColor[1]:=q;
            FColor[2]:=hsva[V];
         end;
         4 : begin
            FColor[0]:=t;
            FColor[1]:=p;
            FColor[2]:=hsva[V];
         end;
         5 : begin
            FColor[0]:=hsva[V];
            FColor[1]:=p;
            FColor[2]:=q;
         end;
      end
   end;
   FColor[3]:=hsva[3];
   NotifyChange(Self);
end;
#3
23:26, 16 июля 2011

петрушка, учись пользоваться гуглом  :I

    public function HSLA2ARGB(h:Number, sl:Number, l:Number, a:Number):uint
    {
      //HSL e [0:1]
      var r:Number = l;
      var g:Number = l;
      var b:Number = l;
      var v:Number = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
      if (v > 0)
      {
        var m:Number, sv:Number, fract:Number, vsf:Number, mid1:Number, mid2:Number;
        var sextant:int;
        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;
        }
      }
      r = limit(int(r * 255), 0, 255);
      g = limit(int(g * 255), 0, 255);
      b = limit(int(b * 255), 0, 255);
      a = int(a * 255);
      return (a << 24) + (r << 16) + (g << 8) + b;
    }
    public function ARGB2HSL(argb:uint):Vec3d
    {
      //HSL e [0:1]
      var r:Number = ((argb >>> 16) % 256) * 0.003921568;
      var g:Number = ((argb >>> 8) % 256) * 0.003921568;
      var b:Number = (argb % 256) * 0.003921568;
      var v:Number, m:Number, vm:Number, r2:Number, g2:Number, b2:Number;
      var h:Number = 0; // default to black
      var s:Number = 0;
      var l:Number = 0;
      var out:Vec3d = new Vec3d();
      v = Math.max(r, g);
      v = Math.max(v, b);
      m = Math.min(r, g);
      m = Math.min(m, b);
      l = (m + v) * 0.5;
      if (l <= 0) return out;
      vm = v - m;
      s = vm;
      
      if (s > 0)
        s /= (l <= 0.5) ? (v + m) : (2 - v - m);
      else
        return out;
      
      r2 = (v - r) / vm;
      g2 = (v - g) / vm;
      b2 = (v - b) / vm;
      
      if (r == v)
      {
        h = (g == m ? 5.0 + b2 : 1.0 - g2);
      }
      else if (g == v) 
      {
        h = (b == m ? 1.0 + r2 : 3.0 - b2);
      }
      else 
      {
        h = (r == m ? 3.0 + g2 : 5.0 - r2);
      }
      h /= 6.0;
      out.Set(h, s, l);
      return out;
    }
#4
23:29, 16 июля 2011

vap
спасибо, с этим кодом-то разберусь. )

#5
9:46, 17 июля 2011

vap
> HSLA2ARGB
HSLA2ARGB
=(

ФлеймФорумПрограммирование

Тема в архиве.