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

Вниз

Есть цвет фона, надо вычислить наиболее контрастный цвет для   Найти похожие ветки 

 
Вин2   (2005-06-12 02:12) [0]

текста на нём. Как это можно сделать ?


 
ssk ©   (2005-06-12 02:14) [1]

инвертируй цвет фона


 
Вин2   (2005-06-12 04:24) [2]

Инвертируй серый цвет.


 
Defunct ©   (2005-06-12 04:50) [3]

Вин2   (12.06.05 04:24) [2]

Пробовать разные цвета, если "на ухо наступил медведь и вкуса нет", тогда обращаться за помощью к дизайнерам.


 
-=XP=- ©   (2005-06-12 07:52) [4]

Исходя из того, что наиболее контрастные и наиболее сочетаемые с другими цвета - черный и белый:

if (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) >= 384 then
 BackColor := clBlack
else
 BackColor := clWhite;


P.S. Иначе надо ударяться в колористику, работать с таблицами цветов, искать формулы счастья созерцания экранного разноцветия - этого, боюсь, многие пользователи не поймут.
P.P.S. Хотя, не исключено, что существует какая-то простенькая формулка. Ибо все гениальное - просто. ;)


 
Anatoly Podgoretsky ©   (2005-06-12 11:46) [5]

Таблица соответсвия


 
Ученик   (2005-06-12 12:17) [6]

Присоединяюсь к вопросу Вин2   (12.06.05 02:12)  

Вариант -=XP=- ©   (12.06.05 07:52) [4] хорош, но, например, для RGB (0, 255, 0) - светло-зеленый, будет выдаваться clWhite, хотя (на первый взгляд) лучше смотрится черный.

>Anatoly Podgoretsky ©   (12.06.05 11:46) [5]
Какого плана таблица ?


 
Alx2 ©   (2005-06-12 12:24) [7]

Если наиболее  контрастный понимать как наиболее удаленный от заданного в системе RGB, то таких цветов будет всего 8 (углы куба в координатах RGB).

Соответственно, находить его можно как
if r>127 then r:=0 else r:=255;
if g>127 then g:=0 else g:=255;
if b>127 then b:=0 else b:=255;

ContrastColor := RGB(r,g,b);

Или, что одно и тоже:

r := (1-(r shr 7))*255
g := (1-(g shr 7))*255
b := (1-(b shr 7))*255


 
Anatoly Podgoretsky ©   (2005-06-12 12:26) [8]

На 6 элементов of TColor, объединяются страршии биты RGB как индекс таблицы, получаются индекс от 0 до 5. Гарантрировано не только контрасность, но и совместимость цветов по вкусу.
Если такая точность недостаточно, то тогда по два старших бита и таблица на 64 элемента, но это уже перебор.


 
Ученик   (2005-06-12 12:36) [9]

>Alx2 ©   (12.06.05 12:24) [7]

Увеличение вариантов цветов возможно ?

>Anatoly Podgoretsky ©   (12.06.05 12:26) [8]

Сами значения массива выбираются на свой вкус или они определены ?


 
Alx2 ©   (2005-06-12 12:42) [10]

>Ученик   (12.06.05 12:36) [9]

Если в том смысле, что я написал - нет. У куба восемь углов -> 8 экстремальных точек.

Можно попробовать еще другие системы цветовых координат (LaB, LHS,..). Но сколько там будет  - не проверял.


 
Борыч   (2005-06-12 12:44) [11]

в большинстве случаев приемлемо:

function ContrastColor(AColor: TColor): TColor;
const TolerSq = 16 * 16;
begin
 if Sqr(GetRValue(AColor) - $80) + Sqr(GetGValue(AColor) - $80)
  + Sqr(GetBValue(AColor) - $80) < TolerSq then
  Result := (AColor + $7F7F7F) and $FFFFFF
 else
  Result := AColor xor $FFFFFF;
end;

© MBo


 
Ученик   (2005-06-12 12:45) [12]

>Alx2 ©   (12.06.05 12:42) [10]
Спасибо за Ваши ответы


 
Anatoly Podgoretsky ©   (2005-06-12 12:46) [13]

Ученик   (12.06.05 12:36) [9]
Немного ошибся 0 на 8 элементов. Насчет выбора - выбрать желаемые ручками, дает наиболее приемлемый результат. Но если цвета устраивают, то предложеное Alx2


 
Ученик   (2005-06-12 12:57) [14]

>Борыч   (12.06.05 12:44) [11]
Попробовал для RGB(128, 128, 192) - получилось не очень, хотя итоговых цветов гораздо больше.


 
Anatoly Podgoretsky ©   (2005-06-12 13:06) [15]

Результат с таблицей подстановки дает более приемлемые результаты. Для оценки на экране делается тибличка 16*16 или более и глазами смотритс, тут же можно подобрать желаемый цвет для таблицы подстановки. Как я сказал можно такое делать или по одному или по двум старщим битам, если нужно большая селективность. Но как правило уже по одному старшему биту достаточно. Достоинство таблицы именно в гибкости, подстройка под персональный вкус.


 
Alx2 ©   (2005-06-12 13:25) [16]

Вариант Бориса (MBo)
Имеет минимум в расстоянии при исходном цвете RGB(127,127,112).
Надпись, сделанная цветом ContrastColor(RGB(127,127,112)) на фоне цветом RGB(127,127,112) практически не читается.


 
Ученик   (2005-06-12 14:40) [17]

>Anatoly Podgoretsky ©   (12.06.05 13:06) [15]

Если не секрет, как Вы закрашиваете табличку 16*16 ?


 
Anatoly Podgoretsky ©   (2005-06-12 14:44) [18]

Ну например на канве 16*16 квадратиков, или просто такое же количество TLabel - нужно же только для визуализации результата, как например в настройках цветов в среде Дельфи. Меняешь цвет и сразу видишь результат.

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


 
Ученик   (2005-06-12 14:50) [19]

>Anatoly Podgoretsky ©   (12.06.05 14:44) [18]
Вопрос в формировании цвета фона для конкретной ячейки, он же, наверно, формируется по какому-то выражению ?


 
Просто Джо ©   (2005-06-12 14:54) [20]


>  [19] Ученик   (12.06.05 14:50)
> Вопрос в формировании цвета фона для конкретной ячейки,
> он же, наверно, формируется по какому-то выражению ?

Да формула проста: I like it :^)


 
Ученик   (2005-06-12 14:57) [21]

>Просто Джо ©   (12.06.05 14:54) [20]

А более конкретный ответ есть ?


 
Anatoly Podgoretsky ©   (2005-06-12 15:01) [22]

Ученик   (12.06.05 14:50) [19]
Ну по вкусу, например с шагом 64 для RGB, получится 4^3 = 64, это вполне достаточно, промежуточные цвета мало отличаются. Речь естественно идет о фоне.


 
Ученик   (2005-06-12 15:12) [23]

>Anatoly Podgoretsky ©   (12.06.05 15:01) [22]

Пример кода, в Вашем варианте вместо вопросиков что написать ?


procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
 Rect: TRect; State: TGridDrawState);
begin
 DrawGrid1.Canvas.Brush.Color := ?????;
 DrawGrid1.Canvas.Font.Color := ContrastColor(DrawGrid1.Canvas.Brush.Color);
 DrawGrid1.Canvas.TextRect(Rect, Rect.Left + 2, Rect.Top + 3, "Текст")
end;



 
Anatoly Podgoretsky ©   (2005-06-12 15:24) [24]

000000
000040
000080
0000С0
//0000FF
004000
...
0040С0
//0040FF
...
C00000
..C0C0
//00FFFF
//FF0000
...
//FFFFFF

for R := 0 TO 3 //4 для FF
 for G := 0 TO 3 //4 для FF
   for B := 0 TO 3 //4 для FF

формирование TColor 64 или 125 базовых цветов для фона.
Тут общий принцип, с TLabel цвета фона можно статически указать в дизайн тайм.


 
Anatoly Podgoretsky ©   (2005-06-12 15:27) [25]

Эталон 01-03 _00__01__02__03_
Эталон 04-07 _04__05__06__07_
...
Эталон 60-63 _60__61__62__63_


 
Ученик   (2005-06-12 15:29) [26]

>Anatoly Podgoretsky ©   (12.06.05 15:24) [24]
Согласить, как-то не очень, но Ваша идея по формированию цвета стала понятна, спасибо за ответ.


 
Anatoly Podgoretsky ©   (2005-06-12 15:30) [27]

Если надо просмотреть для всех 16 миллонов цветов, то не представляю, кроме перевода в другую цветовую плоскость.


 
Anatoly Podgoretsky ©   (2005-06-12 15:31) [28]

Ученик   (12.06.05 15:29) [26]
Посмотри как сделана в Дельфи настройка цветов редактора.


 
Anatoly Podgoretsky ©   (2005-06-12 15:33) [29]

Еше слева от эталона можно разместить три TTrackBar, по одному на RFB со значением 0..63 для изменения младщих 6 бит каждого цвета. Но это уже излишество.


 
Ученик   (2005-06-12 15:35) [30]

>Anatoly Podgoretsky ©   (12.06.05 15:31) [28]
Имеется ввиду стандартный TColorDialog ?


 
Anatoly Podgoretsky ©   (2005-06-12 15:48) [31]

Нет, TColorDialog там для выбора цвета, а суть в образцах (шаблонах), что бы сразу видеть совместимость цветов. Различие там, в том что можно задавать фон и цвет символов, а для данной задачи это не требуется, поскольку идет речь о подборе к фиксированому фону. Разброс или из 8 или из 64 базовых цветов. Задача билзкая по сути.


 
Ученик   (2005-06-12 20:00) [32]

Тема заинтересовала :-), тестовый "вырос" в это, может есть еще варианты



uses
 GraphUtil;

{ тестовая таблица 16 * 16 }

function ContrastColor(AColor: TColor; aMethod: Integer): TColor;
const
 TolerSq = 16 * 16;
var
 R, G, B: Word;
 Hue, Luminance, Saturation: Word;
begin
 R := GetRValue(aColor);
 G := GetGValue(aColor);
 B := GetBValue(aColor);

 if aMethod = 0 then begin  { -=XP=- }
   if R + G + B <= 384 then
     Result := clWhite
   else
     Result := clBlack
 end else if aMethod = 1 then begin { Alx2 }
   if R > 127 then R := 0 else r := 255;
   if G > 127 then G := 0 else g := 255;
   if B > 127 then B := 0 else b := 255;
   Result := RGB(R, G, B)
 end else if aMethod = 2 then begin { MBO }
   if Sqr(GetRValue(AColor) - $80) + Sqr(GetGValue(AColor) - $80)
       + Sqr(GetBValue(AColor) - $80) < TolerSq then
     Result := (AColor + $7F7F7F) and $FFFFFF
   else
     Result := AColor xor $FFFFFF;
 end else
   Result := aColor
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 DrawGrid1.DefaultColWidth := 44;
 DrawGrid1.DefaultRowHeight := 26;
 DrawGrid1.FixedCols := 0;
 DrawGrid1.FixedRows := 0;
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
 DrawGrid1.Invalidate;
 DrawGrid1Click(nil);
end;

procedure TForm1.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
 Rect: TRect; State: TGridDrawState);
begin
 DrawGrid1.Canvas.Brush.Color := ColorHLSToRGB(aRow * 15, aCol * 15, 240);
 DrawGrid1.Canvas.Font.Color := ContrastColor(DrawGrid1.Canvas.Brush.Color, RadioGroup1.ItemIndex);
 DrawGrid1.Canvas.FillRect(Rect);
 DrawText(DrawGrid1.Canvas.Handle,
          PChar("&#210;&#229;&#234;&#241;&#242;"#13 + IntToStr(aRow * 15) + " " + IntToStr(aCol * 15)),
          -1, Rect, DT_CENTER or DT_WORDBREAK)
end;

procedure TForm1.DrawGrid1Click(Sender: TObject);
begin
 Panel1.Color := ColorHLSToRGB(DrawGrid1.Row * 15, DrawGrid1.Col * 15, 240);
 Label1.Font.Color := ContrastColor(Panel1.Color, RadioGroup1.ItemIndex)
end;


 
GuAV ©   (2005-06-12 20:44) [33]

Имхо, method 1 даёт хорошие результаты, если учитывать коэфициеты цветов.

end else if aMethod = 3 then begin  { -=XP=- }
  if R + G * 2 + B <= 430 then
    Result := clWhite
  else
    Result := clBlack


Думаю, хорошей идеей будет выбор между clWhite и clBlack, а порог для всех 16ти строк выбрать руками.


 
GuAV ©   (2005-06-12 20:57) [34]

Нашел формулу:
   Y = 0.299R + 0.587G + 0.114B

if 0.299*R + 0.587*G + 0.114*B <= 120 then

- думаю можно так и оставить.


 
Anatoly Podgoretsky ©   (2005-06-12 21:01) [35]

Вот четыре стандарта перевода в шкалу серого
1. 0,360*R + 0.530*G + 0.110*B
2. Стандаpт CCIR 601-1 (как в стандаpтной VGA-ой функции):
  0,299*R + 0,587*G + 0,114*B
3. Стандаpт CCIR 709:
  0,213*R + 0,715*G + 0,072*B
4. Стандаpт ITU:
  0,222*R + 0,707*G + 0,071*B

Второй как раз наиболее оптимальный для мониторов RGB.


 
Anatoly Podgoretsky ©   (2005-06-12 21:04) [36]

GuAV ©   (12.06.05 20:44) [33]
Думаю, хорошей идеей будет выбор между clWhite и clBlack, а порог для всех 16ти строк выбрать руками.

С этим тоже согласен.


 
Ученик   (2005-06-12 21:25) [37]

>GuAV ©   (12.06.05 20:44) [33]
>Anatoly Podgoretsky ©   (12.06.05 21:01) [35]
Да похоже, два цвета это оптимальный выбор, большое спасибо всем отвечавшим, по, крайней мере, от меня.

>Anatoly Podgoretsky ©   (12.06.05 21:01) [35]
Скрывали, да :-)

Только вот с самой таблицей Ученик (12.06.05 20:00) [32] есть небольшие (или большие) проблемы, серого не видно :-(


 
Anatoly Podgoretsky ©   (2005-06-12 21:30) [38]

Ученик   (12.06.05 21:25) [37]
Ну не совсем, намек был сделан в Anatoly Podgoretsky ©   (12.06.05 15:30) [27], а к решению подошли постепенно, совместными усилиями.


 
GuAV ©   (2005-06-12 21:31) [39]


> if 0.299*R + 0.587*G + 0.114*B <= 120 then


Небольшая поправочка 0.299 + 0.587 + 0.114 = 1, поэтому

if 0.299*R + 0.587*G + 0.114*B <= 127 then

можно попробовать оптимизировать (за счёт точности) сведя к целочисленным сдвигам, вроде [33].
или к целочисленному умножению (если оно быстрее вещесвенного, в чём не уверен).


 
GuAV ©   (2005-06-12 21:33) [40]

Ученик   (12.06.05 21:25) [37]
Только вот с самой таблицей Ученик (12.06.05 20:00) [32] есть небольшие (или большие) проблемы, серого не видно :-(


Если таки остановится на "или clWhite или clBlack", то небольшие, иначе хуже, попытка поцветной инверсии серого даст тот же серый.



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

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

Наверх




Память: 0.57 MB
Время: 0.057 c
14-1118922902
pasha_golub
2005-06-16 15:55
2005.07.18
Yacc&amp;Lex


1-1119957354
olevacho_
2005-06-28 15:15
2005.07.18
шифрация данных в текстовом файле


14-1119528426
Sir John
2005-06-23 16:07
2005.07.18
Новые компоненты Делфи )))


1-1119604820
heckfy1
2005-06-24 13:20
2005.07.18
Свойства принтера


1-1120042840
Shuma
2005-06-29 15:00
2005.07.18
RichEdit - единицы измерения