Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];

Вниз

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 вся ветка

Форум: "Media";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.037 c
3-1094353055
Новенький
2004-09-05 06:57
2004.10.03
Ключи и индексы


14-1095339796
Soft
2004-09-16 17:03
2004.10.03
Suicide.


8-1089603221
Nolf
2004-07-12 07:33
2004.10.03
Плагин к Winamp у


1-1095612885
ВиТ
2004-09-19 20:54
2004.10.03
Регулярные выражения


4-1093109098
AlexV
2004-08-21 21:24
2004.10.03
Label, независимый от размера шрифта в настр-ах Windows ...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский