Преобразование цвета RGB из-в HLS

Материал из DRKB


{ Максимальные значения }
const
  HLSMAX = 240;
  RGBMAX = 255;
  UNDEFINED = (HLSMAX * 2) div 3;
var
  H, L, S: Integer; { H-оттенок, L-яркость, S-насыщенность }
  R, G, B: Integer; { цвета }

procedure RGBtoHLS;
var
  cMax, cMin: Integer;
  Rdelta, Gdelta, Bdelta: Single;
begin
  cMax := Max(Max(R, G), B);
  cMin := Min(Min(R, G), B);
  L := Round((((cMax + cMin) * HLSMAX) + RGBMAX) / (2 * RGBMAX));

  if (cMax = cMin) then
  begin
    S := 0;
    H := UNDEFINED;
  end
  else
  begin
    if (L <= (HLSMAX/2)) then
      S := Round((((cMax - cMin) * HLSMAX) + ((cMax + cMin) / 2)) / (cMax + cMin))
    else
      S := Round((((cMax - cMin) * HLSMAX) + ((2 * RGBMAX - cMax - cMin) / 2)) / (2 * RGBMAX - cMax - cMin));
    Rdelta := (((cMax - R) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
    Gdelta := (((cMax - G) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
    Bdelta := (((cMax - B) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
    if (R = cMax) then
      H := Round(Bdelta - Gdelta)
    else if (G = cMax) then
      H := Round((HLSMAX / 3) + Rdelta - Bdelta)
    else
      H := Round(((2 * HLSMAX) / 3) + Gdelta - Rdelta);
    if (H < 0) then
      H := H + HLSMAX;
    if (H > HLSMAX) then
      H := H - HLSMAX;
  end;
  if S < 0 then S := 0;
  if S > HLSMAX then S := HLSMAX;
  if L < 0 then L := 0;
  if L > HLSMAX then L := HLSMAX;
end;

procedure HLStoRGB;
var
  Magic1, Magic2: Single;

  function HueToRGB(n1, n2, hue: Single): Single;
  begin
    if (hue < 0) then hue := hue + HLSMAX;
    if (hue > HLSMAX) then hue := hue -HLSMAX;
    if (hue < (HLSMAX / 6)) then
      Result := (n1 + (((n2 - n1) * hue + (HLSMAX / 12)) / (HLSMAX / 6)))
    else if (hue < (HLSMAX / 2)) then
      Result := n2
    else if (hue < ((HLSMAX * 2) / 3)) then
      Result := (n1 + (((n2 - n1) * (((HLSMAX * 2) / 3) - hue) + (HLSMAX / 12)) / (HLSMAX / 6)))
    else
      Result := (n1);
  end;

begin
  if (S = 0) then
  begin
    B := Round((L * RGBMAX) / HLSMAX);
    R := B;
    G := B;
  end
  else
  begin
    if (L <= (HLSMAX / 2)) then
      Magic2 := (L * (HLSMAX + S) + (HLSMAX / 2)) / HLSMAX
    else
      Magic2 := L + S - ((L * S) + (HLSMAX / 2)) / HLSMAX;
    Magic1 := 2 * L - Magic2;
    R := Round((HueToRGB(Magic1, Magic2, H + (HLSMAX / 3)) * RGBMAX + (HLSMAX / 2)) / HLSMAX );
    G := Round((HueToRGB(Magic1, Magic2, H) * RGBMAX + (HLSMAX / 2)) / HLSMAX );
    B := Round((HueToRGB(Magic1, Magic2, H - (HLSMAX / 3)) * RGBMAX + (HLSMAX / 2)) / HLSMAX );
  end;
  if R < 0 then R := 0;
  if R > RGBMAX then R := RGBMAX;
  if G < 0 then G := 0;
  if G > RGBMAX then G := RGBMAX;
  if B < 0 then B := 0;
  if B > RGBMAX then B := RGBMAX;
end;


Author: Зайцев О.В.
Author: Владимиров А.М.
Source: http://forum.sources.ru
ID: 03671