Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.03;
Скачать: CL | DM;

Вниз

HLS перевести в RGB   Найти похожие ветки 

 
Tahion2   (2004-07-08 17:29) [0]

У меня есть значения HLS цвета. Мне их нужно конвертированть в соответствующие значения RGB. Для этого есть такая ф-ция:

procedure HLStoRGB(H, L, S: Integer; var R, G, B: Integer);
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;


Обьясните, как она работает?


 
Огромное Кулясищще ©   (2004-07-08 18:51) [1]

http://semmix.pl/color/extrans/etr50.htm


 
Tahion2   (2004-07-08 19:15) [2]

Это все хорошо, но мне бы хотелось получить закомментированный код именно ПРИВЕДЕННОЙ ВЫШЕ процедуры.

P.S. Такое впечатление, что все вопросы можно отправлять сразу тебе, а не в конференцию :)


 
wicked ©   (2004-07-08 22:17) [3]


> Tahion2 [2]

упрямый какой - чужие исходники, да с комментами...
найди delphi 6, там в исходниках vcl есть модуль graphutil.pas...
в нём есть как раз такая функция, там даже немного комментариев разбросано...


 
Огромное Кулясищще ©   (2004-07-08 22:34) [4]

Исходники то не полные. Откуда же я знаю значения констант :)


 
Tahion2   (2004-07-09 11:42) [5]


> Исходники то не полные. Откуда же я знаю значения констант
> :)


Любой каприз, сэр:
Const
 HLSMAX=240;
 RGBMAX=255;
 UNDEFINED=(HLSMAX*2)div 3;


 
Огромное Кулясищще ©   (2004-07-09 13:36) [6]

Так, ч честно пытасно закомментировать, но а) лень б) невозможно, если человек не знает, что отображает Hue

Поэтому, что вот получившееся:


const

 { Максимальное значение для H, L и S. Дело в том, что в реальности
   H является углом и принимает значения 0..360, а L и S принимают
   значения от 0 до 1 (например, 0.1). Однако по принципу типа RGB
   нужно, чтобы HLS принимало значения в пределах типа Byte. Можно было
   бы присвоить HLSMAX = 255, но дело в том, что хорошо бы, если HLSMAX
   делится на 6 (или даже на 12), поэтому взяли HLSMAX = 240 }

 HLSMAX = 240;

 { Максимальное значений каждой из состовляющих значение RGB.
   Напомню, что RGB кодируется тремя состовляющими - красного (R),
   зелёного (G) и синего (B) цветов, каждая из которых может принимать
   значения от 0 до 255 [всего 256 значений] }

 RGBMAX = 255;

procedure HLStoRGB(H, L, S: Integer; var R, G, B: Integer);
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;

 // Hue можно рассматривать как угол, причём полный угол будет 240, а не 360
 // градусов. Повернуть на 250 градусов в нашем случае будет то же самое, что
 // повернуть на 250-240=10 градусов. Именно это и делает приведённый выше код.

 // Теперь представим, что HLSMAX = 360 градусов. Тогда...

 if (hue < (HLSMAX / 6)) then  // если < 60 градусов
   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

{ Когда насыщенность равна 0, то значение Hue (да и Saturation) можно
 не принимать в расчёт, потому что получается grayscale и все значений R,G,B равны
 друг другу }

if (S = 0) then
 begin
   // L / HLSMAX - % освещённости. Умноженный на RGBMAX даст освещённость
   // пропорционально в пределах [0..255]. Помни, что RGB(255,255,255) - это
   // белый, т.е. чем больше L в этом случае, тем светлее оттенок серого.

   B := Round((L * RGBMAX) / HLSMAX); R := B; G := B;
 end

{ Начинается основная работа.  }

else
 begin

   // Если всё же взглянуть на схему
   // http://semmix.pl/color/extrans/etr50.htm
   // то можно заметить почему так

   if (L <= (HLSMAX / 2)) then
     Magic2 := (L * (HLSMAX + S) + (HLSMAX / 2)) / HLSMAX
   else
     Magic2 := L + S - ((L * S) + (HLSMAX / 2)) / HLSMAX;

   { Magic имеет тип Single и лежит в пределах от 0 до 1 - так
     должно быть в настоящем представлении HLS }

   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;

{ Проверка на выход значений из границ дозволеного.
 Если значение меньше 0, то оно приравнивается
 к минимальному, т.е. 0, если оно больше 255, то оно
 приравнивается к максимальному, т.е. 255 }
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;


И ещё раз:

Вдумчиво прочитай это:
http://semmix.pl/color/models/emo18.htm

и когда код читаешь, то пусть открыто вот это:
http://semmix.pl/color/extrans/etr50.htm

max(r,g,b) и min(r,g,b) - это из этой оперы:
http://semmix.pl/color/extrans/etr30.htm


 
Огромное Кулясищще ©   (2004-07-09 13:38) [7]

Ещё:
http://www.fho-emden.de/~hoffmann/hlscone03052001.pdf

На странице 3 - интересная таблица, а далее по страницам есть код, где более понятно, куда какой градус.


 
Tahion2   (2004-07-09 15:53) [8]

Может еще к вот этому можно комментарий придумать?

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


 
Jeer ©   (2004-07-09 16:38) [9]

Ну вот - лабораторка почти и сделана, главное - нахаляву:))


 
Tahion2   (2004-07-10 09:05) [10]

Ну не совсем сделана, и совсем не лабораторка, так что.... :)


 
Огромное Кулясищще ©   (2004-07-10 15:35) [11]

Magic1 и Magic2 хранят информацию о Saturation и Lightness, эта информация передаётся в HueToRGB через эти переменные. Далее, информация о Hue передаётся отдельно для R, G, B, так как по идее, Hue - это уже цвет, но нам то его нужно разлагать. Как видишь, добавляется 120 градусов (в коде это 240 / 3 = 80) - а это значит, что берутся три равноудалённые точки (см. теорию про цветовое колесо).


 
Огромное Кулясищще ©   (2004-07-11 17:00) [12]

Недавно переустанавливал систему, заодно порылся в папках и нашёл интересную ссылочку, которая поможет понять цветовое колесо Hue (где-какой цвет):
http://www.chaospro.de/documentation/html/formulacompiler/languagereference/functions/color/hsl.htm



Страницы: 1 вся ветка

Текущий архив: 2004.10.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.022 c
4-1093619620
Sunny Way
2004-08-27 19:13
2004.10.03
Доступ к пикселам постороннего окна


14-1095338151
infom
2004-09-16 16:35
2004.10.03
Как у вас с логикой ?


3-1094036403
Andrey
2004-09-01 15:00
2004.10.03
Создание псевдонима при инсталяции


14-1094798237
PVOzerski
2004-09-10 10:37
2004.10.03
Есть ли sudo и альтернативные системы ввода пароля для NT?


14-1095408469
Baks
2004-09-17 12:07
2004.10.03
Календарик