Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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.116 c
4-1092979626
RagE
2004-08-20 09:27
2004.10.03
Оконная процедура и класс


1-1094607254
Sollo
2004-09-08 05:34
2004.10.03
Импорт функций из sys файлов


14-1095162390
Knight
2004-09-14 15:46
2004.10.03
Можно ли использовать помощников MS в своих программах?


3-1094107762
strelok-47
2004-09-02 10:49
2004.10.03
отлов момента ввода инфы в поле


6-1090675089
banderas
2004-07-24 17:18
2004.10.03
idTCPServer &amp; idTCPClient1 передача служебной информации





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский