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

Вниз

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

 
Вин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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.043 c
4-1116951848
Lamer8
2005-05-24 20:24
2005.07.18
SHFileOperation


14-1119789328
Chuvak
2005-06-26 16:35
2005.07.18
DVD+-RW?


3-1118307115
ShotGuN
2005-06-09 12:51
2005.07.18
Копирование массива данных


14-1119580587
sybrex
2005-06-24 06:36
2005.07.18
сделать demo версию программы


14-1118903822
Ломброзо
2005-06-16 10:37
2005.07.18
Подавитесь





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