Форум: "Media";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];
ВнизОтобразить картинку в оттенках определенного цвета (Colorize) Найти похожие ветки
← →
Tahion2 (2004-07-07 10:01) [0]Мне нужно отобразить картинку в оттернах определенного цвета. Выглядеть должно так, вроде ты смотришь на картинку через стекло заданого цвета.
Общий смысл процедуры таков: пробегаем по каждому пикселю битмапа, RGB -> HLS, и затем замена H и S на нужные нам, а L оставляем нетронутым.
Все, вроде, работает, но на темных цветах происходят непонятные "срывы". См. иллюстрацию (Правый результат): http://www.rudnik.com.ua/Example.gif
Вопрос: Что не так я делаю. Где ошибка?
Вот код, который я использую:procedure RGBtoHLS(R, G, B: Integer; var H, L, S: Integer);
{ H-оттенок, L-яркость, S-насыщенность }
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(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;
procedure ColorizeColor(R,G,B :integer; Color: TColor; var OutR, OutG, OutB:Byte);
//Колоризирует один пиксель цветом Color
var h1, s1, l1, h, s, l : integer;
InColor, OutColor : TColor;
R1,B1,G1:integer;
begin
InColor := RGB(R,G,B);
RGBtoHLS(R, G, B, h, l, s);
RGBtoHLS(GetRValue(Color), GetGValue(Color), GetBValue(Color), h1, l1, s1);
HLStoRGB(h1,l,s1, r1,g1,b1);
OutColor:= RGB(r1,g1,b1);
OutR:=GetRValue(OutColor);
OutG:=GetGValue(OutColor);
OutB:=GetBValue(OutColor);
end;
//Next here"s a code to make a loop on an image (called Podglad, size is 32*32):
//В данном случае происходит раскраска красным цветом.
var OutR, OutG, OutB:Byte;
Col:TColor;
begin
for y := 0 to 31 do
for x := 0 to 31 do
begin
Col:=Podglad.Picture.Bitmap.Canvas.Pixels[x, y];
ColorizeColor(GetRValue(Col),GetGValue(Col),GetBValue(Col), clRed, OutR, OutG, OutB);
Podglad.Picture.Bitmap.Canvas.Pixels[x, y]:=RGB(OutR, OutG, OutB);
end;
end;
← →
REA © (2004-07-07 10:07) [1]Локализуй неверный пиксел, просчитай значение вручную и по шагам....
← →
Tahion2 (2004-07-07 10:49) [2]Что значит "Локализуй неверный пиксел"? они при определенных цветах все неверные.
Юпросчитай значение вручную
Проверил HLStoRGB и RGBtoHLS работают правильно.
Может еще какие-то действия с L (lightness) нужно делать?
← →
REA © (2004-07-07 11:10) [3]Ты алгоритм сам изобрел? Если ты знаешь критерий неправильности, то знаешь и как правильно. Осталось сравнить.
Модуль GraphUtil:
procedure ColorRGBToHLS(clrRGB: COLORREF; var Hue, Luminance, Saturation: Word);
{ Calculates a color given Hue, Luminance and Saturation values }
function ColorHLSToRGB(Hue, Luminance, Saturation: Word): TColorRef;
Если версия Delphi старая, то могу кинуть целиком функции
← →
Tahion2 (2004-07-07 11:39) [4]>Ты алгоритм сам изобрел? Если ты знаешь критерий неправильности, то знаешь и как правильно. Осталось сравнить.
Нет, не сам. В этом все и дело.
А как правильно я знаю из-за того, что есть программы, которые алгоритм уже реализуют (ПРАВИЛЬНО). Сравинивая их и мои результаты получаю ответ: правильно или нет
← →
Tahion2 (2004-07-07 13:47) [5]Может кто чего подсказать?
← →
Огромное Кулясищще © (2004-07-07 14:37) [6]http://delphibase.endimus.ru/?action=viewfunc&topic=mediaimg&id=10178
← →
Tahion2 (2004-07-07 15:30) [7]Эта функция глючит еще сильнее. То что в результатах на картинке
http://www.rudnik.com.ua/Example.gif
слева - это после работы именно этой ф-ции.
← →
Огромное Кулясищще © (2004-07-07 20:39) [8]Щас, ты погодь. Сваяю что-нить, раз Fenik плохой алгоритм сделал :)
← →
Tahion2 (2004-07-07 22:09) [9]Ждем-с
← →
Огромное Кулясищще © (2004-07-07 22:25) [10]Первый блин. Комочки большие, но всё же.
http://www.hot.ee/mvps17/exampel2.png
← →
Tahion2 (2004-07-08 00:26) [11]Да. Уже неплохо. :)
Вот только здается мне, что алгоритм с RGB -> HLS и заменой Н и S правильный, вот только еще что-то нужно делать с L. Вот только что?
← →
REA © (2004-07-08 10:59) [12]А в GraphUtil кривые функции?
← →
Tahion2 (2004-07-08 13:34) [13]>А в GraphUtil кривые функции?
Да нет. нормальные ф-ции. Но проблема наверняка не в них. Я проверил уже и на ф-циях из GraphUtil. Рузультат одинаковый. Явно еще что-то нужно делать с L. Только что?
← →
REA © (2004-07-08 14:36) [14]Дурацкий вопрос: а почему все операции с L, может быть попробовать Hue - все-таки оно отвечает за оттенок?
Можно еще разложить "правильный" результат в HLS и сравнить значения, которые есть и которые надо.
← →
Tahion2 (2004-07-08 16:58) [15]>Дурацкий вопрос: а почему все операции с L, может быть попробовать Hue - все-таки оно отвечает за оттенок?Как раз наоборот. На данный момент именно L остается не тронутым, заменяется оттенок и насыщеность.
>Можно еще разложить "правильный" результат в HLS и сравнить значения, которые есть и которые надо.Вот. Сравнил 15 столбец. Вот сначения HLS для третьего сверху цвета колоризации (из тех, что на картинке http://www.rudnik.com.ua/Example.gif)Правильный Мой
40 121 172 41 67 112
40 150 240 40 87 238
40 155 240 40 95 238
40 151 240 40 91 238
40 146 240 40 88 238
40 144 240 40 86 238
40 144 240 40 87 238
40 144 240 40 89 238
40 139 240 40 85 238
40 143 240 40 88 238
40 196 240 40 139 238
40 190 240 40 133 240
40 158 240 40 102 238
40 121 240 40 65 237
40 140 240 40 86 238
40 160 240 40 107 238
40 132 240 40 79 238
40 144 240 40 90 238
40 170 240 40 116 239
40 175 240 40 120 239
40 177 240 40 120 239
40 172 240 40 116 239
40 147 240 40 89 238
40 95 238 40 38 234
40 129 240 40 76 238
40 147 240 40 93 238
40 107 238 40 52 236
42 84 45 147 65 11
135 131 9 142 129 14
136 158 14 144 155 20
137 181 27 142 179 34
141 195 43 143 194 47
160 240 0 160 240 0
А вот для красного (первый сверху на картинке). Он вроде правильно колоризирован:Правильный Мой
0 120 172 0 116 170
0 150 240 0 146 238
0 155 240 0 154 240
0 151 240 0 150 238
0 146 240 0 148 240
0 144 240 0 146 240
0 144 240 0 147 240
0 144 240 0 149 240
0 139 240 0 144 240
0 143 240 0 148 238
0 196 240 0 198 235
0 190 240 0 192 240
0 158 240 0 161 238
0 121 240 0 125 240
0 140 240 0 145 238
0 160 240 0 167 240
0 132 240 0 138 240
0 144 240 0 150 238
0 170 240 0 176 240
0 175 240 0 180 240
0 177 240 0 180 237
0 172 240 0 176 240
0 147 240 0 149 240
0 95 238 0 97 238
0 129 240 0 136 238
0 147 240 0 153 240
0 106 238 0 112 238
235 80 48 235 81 50
155 131 9 151 131 10
156 158 14 153 157 15
149 181 27 147 181 29
146 195 43 146 195 43
160 240 0 160 240 0
Кто какую закономерность улавил?
← →
Tahion2 (2004-07-08 17:23) [16]Что вызывает вопрос: У меня значение L скачет отпервого цвета к другому. В правильном же результате оно остается постоянным (примерно). И оно должно оставаться постоянным, ведь начальная картинка одна (значит L в моем и в правильном результате идентичны), при работе алгоритма, я изменяю H и S, но L ОСТАВЛЯЮ ТЕМ ЖЕ!!!
В то же время видно, что в результате оно поменялось.
Если взять еще и третий цвет, то там L опять другое:41 122 58 42 93 48
40 149 80 40 117 79
39 155 81 40 124 79
40 150 80 40 121 80
40 146 80 40 118 79
40 143 80 40 116 80
40 143 80 40 117 79
39 144 80 40 119 80
40 139 80 40 114 80
40 142 80 40 119 80
39 196 82 40 169 79
40 190 79 40 162 80
39 157 80 40 132 80
40 122 82 40 96 79
39 140 80 40 116 80
40 160 80 40 136 80
40 133 79 40 109 80
39 144 80 40 120 80
40 170 80 40 146 80
39 176 80 40 150 80
40 177 80 40 150 80
39 172 82 40 146 80
39 147 80 40 120 79
40 95 80 41 68 79
40 129 80 40 106 80
39 147 80 40 123 79
40 106 80 40 82 80
49 84 13 147 65 11
140 131 11 142 129 14
138 157 18 144 155 20
142 181 31 142 179 34
142 194 45 143 194 47
160 240 0 160 240 0
Значит процедура SHLtoGRB "портит" мне результат. Каким-то образом подменяя L. НО она правильная, поскольку я перебирал результаты трех таких функций. Результаты идентичны.
Тоесть для колоризации должна быть какая-то своя ф-ция SHLtoGRB. Но какая?
P.S. Исходники HLStoRGB сверху страницы.
← →
Огромное Кулясищще © (2004-07-08 17:30) [17]Щас, погодь. У меня получился идеальный Colorize (как на картинке, где через спец.программу), через час я выложу исходники.
← →
Огромное Кулясищще © (2004-07-08 18:36) [18]Вот это чудо:
http://www.hot.ee/mvps17/Example.png
И вот код:
http://www.hot.ee/mvps17/Colorize.rar
← →
Tahion2 (2004-07-08 19:11) [19]Это в смысле то, на которое стрелка показывает?
Если да, то цвет совсем не такой :(
← →
Огромное Кулясищще © (2004-07-08 19:16) [20]Как же он не такой? Он же не оранжевый, как там.
← →
Tahion2 (2004-07-08 19:28) [21]В данном случае картинка какая-то бледная, обезцвеченая. Это очень плохо.
Может тебе мои исходники выложить?
← →
Огромное Кулясищще © (2004-07-08 21:27) [22]Может быть и бледноватая, но заметь - на той картинке, которую ты хочешь получить, предпоследний результат - слишком жёлтый, а последний - оранжевый.
Исходники можешь выложить. Вообще, я работаю через Blending и Grayscale. Скажем, путём блендинга можно получить нечто среднее между моим и твоим.
← →
Tahion2 (2004-07-09 11:41) [23]
> Может быть и бледноватая, но заметь - на той картинке, которую
> ты хочешь получить, предпоследний результат - слишком жёлтый,
> а последний - оранжевый.
Согласен, но именно к этому результату я стремлюсь, а згначит, он для меня идеальный
> Исходники можешь выложить. Вообще, я работаю через Blending
> и Grayscale. Скажем, путём блендинга можно получить нечто
> среднее между моим и твоим.
Вот http://www.rudnik.com.ua/ColorizeDemo.rar
← →
Tahion2 (2004-07-09 15:51) [24]ну?
← →
Огромное Кулясищще © (2004-07-09 21:47) [25]Думается, более оранжевая стала:
http://www.hot.ee/mvps17/another.bmp
Код надо?
← →
Tahion2 (2004-07-10 09:04) [26]>Думается, более оранжевая стала:
Да, но в данном случае икока становится менее четкой. Как я понял ты сначала делаешь ее черно-белой, а затем накладываешь поверх цветной "туман".
От этого иконка становится менее четкой. Более того, сильно меняется цвет ее ТЕНИ.
Может попробуй пойти таким же или подобным моему путем?
P.S. Вот здесь еще проблемка важная:
http://delphimaster.net/view/8-1088862420/
← →
Tahion2 (2004-07-10 09:10) [27]точнее уже здесь:
http://delphimaster.net/view/8-1088862420/
← →
Огромное Кулясищще © (2004-07-10 15:46) [28]>От этого иконка становится менее четкой. Более того, сильно меняется цвет ее ТЕНИ.
Слухай, ты что вообще? Естестественно цвет тени меняется, потому что я работаю с 24-битным изображением, а ты вписал Colorize в загрузку иконки и альфа-канал, создающий тень, грузится отдельно. Я не пишу тебе готовое решение. Я хочу лишь помочь таким наброском, который тебя удовлетворит - остальное (стыковка, оптимизация, устранение багов) ты должен сделать сам.
← →
Огромное Кулясищще © (2004-07-10 16:23) [29]Попробуй всё таки не боятся кодить. Загружай иконку в 32-bit"ное изображение или же вообще используй Graphic32 и его 32-bit"ный формат. Дальше уже легче будет работать с цветами, когда всё под рукой. Ведь если подумать, то реализация TIcon32 в плане того, что иконка каждый раз загружается, довольно плохая. Тебе нужно это переделать.
Если попробовать мои старания в учётом альфа-канала, то может быть выйдет и не так плохо.
← →
Tahion2 (2004-07-10 18:29) [30]ок. давай код.
← →
Огромное Кулясищще © (2004-07-10 19:04) [31]http://www.hot.ee/mvps17/Colorize.rar
Обязательно напиши, что получилось.
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];
Память: 0.59 MB
Время: 0.058 c