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

Вниз

Цвета...   Найти похожие ветки 

 
ThomasXIII ©   (2004-08-27 00:07) [0]

Мастера! Напишите, плиз, процедуру, "усредняющую" цвета (например:красный+желтый=оранжевый или белый+черный=серый). Очень надо.


 
jack128 ©   (2004-08-27 00:10) [1]

переведи цвета в RGB и вредни каждую компоненту цвета по отдельности. И переведи обратно в TColor


> Напишите, плиз, процедуру

Подобные запросы на этом форуме не катируются..


 
jack128 ©   (2004-08-27 00:11) [2]


> переведи цвета в RGB и УСРЕДНИ каждую компоненту


 
3APA3A ©   (2004-08-27 00:26) [3]

Так задачи разные по своей сути...
 Оранжевый - это сложение красного и желтого
 Серый - это среднее между белым и черным...
 
 Для начала ответь на вопрос что надо сделать (сложить или усреднить) что бы получить
  1) Темно-красный
  2) Фиолетовый
  3) Белый


 
GuAV ©   (2004-08-27 00:27) [4]

jack128 ©   (27.08.04 00:10) [1]
Тот же результа, алгоримт оптимизирован.
Color:=((Color1 shr 1) and $7F7F7F + (Color2 shr 1) and $7F7F7F);

Хотя не уверен, что эта идея (твоя) правильная.


>  Оранжевый - это сложение красного и желтого

В RGB сложение даст желтый, а в CMYK красный, в общем случае - неизвестно.


 
GuAV ©   (2004-08-27 00:30) [5]

Раумеется, если компонента переполнена, принять максимум иначе - сам понимаешь, ваще бред.


 
3APA3A ©   (2004-08-27 00:32) [6]

Я имел в виду RGB...


 
jack128 ©   (2004-08-27 00:37) [7]

GuAV ©   (27.08.04 0:27) [4]
Хотя не уверен, что эта идея (твоя) правильная.


ну я увидел слово "усредняющую" и ответил в меру своего скудоумия ;-) решать правильно или нет - автору..


 
GuAV ©   (2004-08-27 00:44) [8]


> ну я увидел слово "усредняющую" и ответил в меру своего
> скудоумия ;-) решать правильно или нет - автору..

Я о том, что лулше это имхо делать в координатах оттенок-контраст-яркость.

Кстати "отптимизорванный" мной алгоритм врёт. но чуть-чуть. на единичку каждого из трёх основных цветов. и то иногда.


 
GuAV ©   (2004-08-27 00:56) [9]


> Я имел в виду RGB...

// "тупое" сложение
procedure TForm1.Button1Click(Sender: TObject);
begin
 Color:=clRed+clYellow; // Почти красный.
end;
// "умное" сложение
procedure TForm1.Button2Click(Sender: TObject);
const color1:tcolor=clred;
const color2:tcolor=clYellow;
var ResultColor:tcolor; I, tmp: integer;
begin
 for I:=0 to 2 do
 begin
   tmp:=
      longrec(Color1).Bytes[i]+
      longrec(Color2).Bytes[i];
   if tmp>high(byte) then tmp:=high(byte);
   longrec(ResultColor).Bytes[i]:=tmp;
 end;
 Color:=ResultColor; // как я и обещал желтый.
end;


 
TUser ©   (2004-08-27 07:35) [10]


> GuAV ©   (27.08.04 00:27) [4]
> jack128 ©   (27.08.04 00:10) [1]
> Тот же результа, алгоримт оптимизирован.
> Color:=((Color1 shr 1) and $7F7F7F + (Color2 shr 1) and
> $7F7F7F);

А как это должно рабоатать. shr передвинет разряды из одного цвета в другой, а надо-то с каждым цветом отдельно работать. И почему надо определенные биты игнорировать - я тоже не понял. Объясните, plz.


 
3APA3A ©   (2004-08-27 11:53) [11]

Млин, я только сейчас сообразил, что ерунда все это -сложение, усреднение, проверка на переполнение...
 По теории - RGB цвет это координаты точки в кубе с главным диагональным вектором (255,255,255) - следовательно, если есть два цвета, то это просто две точки в этом кубе и "средний цвет" это координаты середины отрезка, соединяющего эти две точки ...
 А уж координаты середины отрезка это
  v = ((red1 + red2) div 2, (green1 + green2) div 2 , (blue1 + blue2) div 2)... Вот и "средний цвет"...


 
Rem   (2004-08-27 12:00) [12]

function MixColors(a_Color1, a_Color2: TColor): TColor;
begin
 Result := RGB((GetRValue(a_Color1) + GetRValue(a_Color2)) div 2,
               (GetGValue(a_Color1) + GetGValue(a_Color2)) div 2,
               (GetBValue(a_Color1) + GetBValue(a_Color2)) div 2);
end;


 
GuAV ©   (2004-08-27 14:20) [13]

jack128 ©   (27.08.04 00:10) [1]
3APA3A ©   (27.08.04 11:53) [11]
Rem   (27.08.04 12:00) [12]

Это может и так, но представь в CMYK, в ещё каком представлении, может будет другой результат, если нет, то вперёд.


 
GuAV ©   (2004-08-27 14:22) [14]


> А как это должно рабоатать. shr передвинет разряды из одного
> цвета в другой, а надо-то с каждым цветом отдельно работать.

Да, именно поэтому провалившиеся в чужой разряд биты я игнорирую. Небольшая погрешность, зато самый быстрый алгоритм.


 
nikkie ©   (2004-08-27 15:26) [15]

>Небольшая погрешность, зато самый быстрый алгоритм.
красиво, мне понравилось.


 
GuAV ©   (2004-08-27 18:06) [16]

А вот и исправил - теперь точно:

function GetMixedColorThursday(C1, C2: TColor): TColor;
begin
 Result:=((C1 shr 1) and $7F7F7F + (C2 shr 1) and $7F7F7F) +
   (C1 and C2) and $010101;
end;

И другая идея:

function GetMixedColorFriday(C1, C2: TColor): TColor;
asm
  MOV   ECX, EAX
  PUSH  EDX

  AND   ECX, 0FF00FFh
  AND   EDX, 0FF00FFh
  ADD   ECX, EDX
  SHR   ECX, 1
  AND   ECX, 0FF00FFh

  POP   EDX

  AND   EAX, 000FF00h
  AND   EDX, 000FF00h
  ADD   EAX, EDX
  SHR   EAX, 1
  AND   EAX, 000FF00h

  OR    EAX, ECX
end;


 
GuAV ©   (2004-08-27 19:08) [17]


> красиво, мне понравилось.

Это просто, как биты в байте менять :)


 
nikkie ©   (2004-08-27 19:22) [18]

>Это просто, как биты в байте менять :)
ну давай тогда самый быстрый и элегантный способ перевода цвета в grayscale :)


 
GuAV ©   (2004-08-27 20:11) [19]


> ну давай тогда самый быстрый и элегантный способ перевода
> цвета в grayscale :)

А что под этим понимать? в смысле как в grayscale переводят? в каждую компоненту среднее? или максимум? или находят якрость как Paint? сорее всего как Paint - тогда ща просеку логику и напишу...


 
nikkie ©   (2004-08-27 20:38) [20]

ну по-правильному надо через яркость - там каждая составляющая дает разный вклад.
http://vagrant.dp.ua/Photoshop/7/5.htm

для трюков с битами я имел ввиду прямолинейный способ
Rnew=Gnew=Bnew=(R+G+B)/3


 
nikkie ©   (2004-08-27 20:49) [21]

или только с делением на 2 и чуть ближе к яркостному варианту:
Rnew=Gnew=Bnew=R/4+G/2+B/4


 
GuAV ©   (2004-08-27 22:48) [22]


> Rnew=Gnew=Bnew=(R+G+B)/3

Ничё лучше этого не могу:
function StupidGray(C: TColor): TColor; assembler;
asm
  MOV  EDX, EAX
  AND  EAX, 0000FF00h
  AND  EDX, 00FF00FFh
  SHL  EDX, 8
  ADD  EAX, EDX
  SHR  EDX, 16
  ADD  EAX, EDX // Сумма в AH и следующем байте

  SHR  EAX, 8
  AND  EAX, 0000FFFFh
  XOR  EDX, EDX
  MOV  CX,  3
  DIV  CX

  MOV  AH,  AL
  SHL  EAX, 8
  MOV  AL,  AH
end;


И всё таки TColorDialog считает по другому.
Яркость(красный)=Яркость(желтый)=Яркость(серый)=(Яркость(белый)/2)


 
GuAV ©   (2004-08-28 03:27) [23]

function Gray(C: TColor): TColor; assembler;
asm
  MOV  EDX, EAX
  AND  EAX, 0000FF00h
  AND  EDX, 00FF00FFh
  SHR  EAX, 8
  ADD  EAX, EDX
  SHR  EDX, 16
  ADD  EAX, EDX

  AND  EAX, 0000FFFFh
  XOR  EDX, EDX
  MOV  CX,  3
  DIV  CX

  MOV  AH,  AL
  SHL  EAX, 8
  MOV  AL,  AH
end;


> Rnew=Gnew=Bnew=R/4+G/2+B/4

Это мне на завтра :)


 
GrayFace ©   (2004-08-28 08:20) [24]

Вначале надо делать ColorToRGB.


 
Sectey ©   (2004-08-28 12:24) [25]

GuAV ©
Ты конечно молодец :-)
Классные и быстрые алгоритмы сложения двух цветов НО . . .
Ты их сам то проверял?

clBlue + clYellow НЕ равняется clGreen :-(

А так все хорошо начиналось . . .


 
GuAV ©   (2004-08-28 14:48) [26]


> clBlue + clYellow НЕ равняется clGreen :-(

И не должно !!

в RGB
clGreen = 00FFFF
clBlue = FF0000

Это что я и говорил.
> GuAV ©   (27.08.04 00:27) [4]
> jack128 ©   (27.08.04 00:10) [1]
> Тот же результа, алгоримт оптимизирован.
> Color:=((Color1 shr 1) and $7F7F7F + (Color2 shr 1) and
> $7F7F7F);
>
> Хотя не уверен, что эта идея (твоя) правильная.

>jack128 ©   (27.08.04 00:10) [1]
>3APA3A ©   (27.08.04 11:53) [11]
>Rem   (27.08.04 12:00) [12]
>
> Это может и так, но представь в CMYK, в ещё каком представлении,
> может будет другой результат, если нет, то вперёд.


2GrayFace

>  ColorToRGB

Да, конечно, забыл сказать, но делать лучше вне этих процедур, т.к. может на входе быть уже RGB чтоб лишний раз не делать.


 
GuAV ©   (2004-08-28 15:19) [27]


> Классные и быстрые алгоритмы сложения двух цветов НО . .
> .
> Ты их сам то проверял?

То есть я проверял что даёт средний - GetMixedColorThursday даёт.
А средний между clYellow и clBlue в RGB Green -ом не будет.

По поводу быстрые. Не думай тока, что то что на asm быстрее :)

function GetMixedColorFriday(C1, C2: TColor): TColor;
asm
  MOV   ECX, EAX
  PUSH  EDX

  AND   ECX, 0FF00FFh
  AND   EDX, 0FF00FFh
  ADD   ECX, EDX
  SHR   ECX, 1
  AND   ECX, 0FF00FFh

  POP   EDX

  AND   EAX, 000FF00h
  AND   EDX, 000FF00h
  ADD   EAX, EDX
  SHR   EAX, 1
  AND   EAX, 000FF00h

  OR    EAX, ECX
end;

function GetMixedColorThursday(C1, C2: TColor): TColor;
begin
 Result:=C1 shr 1 and $7F7F7F + C2 shr 1 and $7F7F7F +
   C1 and C2 and $010101;
end;

function GetMixedColorThursday1(C1, C2: TColor): TColor;
begin
 Result:=C1 shr 1 and $7F7F7F + C2 shr 1 and $7F7F7F;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Color := GetMixedColorThursday(clYellow,clRed);
end;

procedure TForm1.Button1Click(Sender: TObject);
const
TestCount = 100000000;
var
A, A1, B: Cardinal;
i: Integer; i1, i2 : tcolor;
begin
 Randomize;
 i1:=Random(Succ(clWhite));
 i2:=Random(Succ(clWhite));

 Assert(
   GetMixedColorThursday(i1,i2) =
   GetMixedColorFriday(i1,i2)
   );

 A := GetTickCount;
 for i := 0 to TestCount do GetMixedColorThursday(i1,i2);
 A := GetTickCount - A;

 A1 := GetTickCount;
 for i := 0 to TestCount do GetMixedColorThursday1(i1,i2);
 A1 := GetTickCount - A1;

 B := GetTickCount;
 for i := 0 to TestCount do GetMixedColorFriday(i1,i2);
 B := GetTickCount - B;

 Caption := Format("Thursday = %d (%d), Friday = %d", [A, A1, B]);
 // Thursday = 708 (504), Friday = 810
end;



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

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

Наверх




Память: 0.53 MB
Время: 0.031 c
3-1098175505
Grizzly
2004-10-19 12:45
2004.11.28
Выгрузка БД в текстовый файл


4-1098254290
AlexTayfun
2004-10-20 10:38
2004.11.28
Изменить цвет чужого окна.


4-1097648493
Woolen
2004-10-13 10:21
2004.11.28
Как загрузить файл exe в память полностью?


14-1100215713
Поручик
2004-11-12 02:28
2004.11.28
bat-файл


4-1097682747
Hmm
2004-10-13 19:52
2004.11.28
isql.exe или как выполнить команду в консольном приложении... ?





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