Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.28;
Скачать: CL | DM;

Вниз

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

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

Текущий архив: 2004.11.28;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.032 c
11-1083127231
earl Grey
2004-04-28 08:40
2004.11.28
HeapMM, KOl и строки


1-1100454101
novice_man
2004-11-14 20:41
2004.11.28
Присваивание или копирование?


3-1098792490
Garry_c
2004-10-26 16:08
2004.11.28
Ограничения на значения ячеек в dbgrid


3-1099066953
MAVOR
2004-10-29 20:22
2004.11.28
ПОИСК


14-1100262738
asdqwer
2004-11-12 15:32
2004.11.28
VOB->AVI