Форум: "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