Kolor kontrastowy

0

Cześć,

piszę aplikację w której potrzebuję nadawać buttonom kolory (pobierane z bazy danych innej - nie mojej - aplikacji). W tej zewnętrznej aplikacji użytkownik wybiera kolor przyciskowi z palety Windows a kolor napisu ustawia się automatycznie tak żeby był dobrze widoczny, z tego co zaobserwowałem to dla "jasnych" przycisków jest to kolor czarny, dla "ciemnych" biały. Te dane nie są zapisywane w bazie.
No i teraz pytanie - jak rozpoznać czy kolor jest jasny czy ciemny? W bazie kolory są zapisywane jako Decimal - od razu pasują jako TColor, np: biały: 16777215, czerwony: 255, pomarańczowy: 33023 itp.

0

Odpowiadam sam sobie (hmm, mogłem jednak lepiej poszukać),

znalazłem bardzo prostą funkcję, która dla jasnych kolorów ustawia kolor na czarny i przeciwnie:

function InvertColor(const Color: TColor): TColor;
begin
  if (GetRValue(Color) + GetGValue(Color) + GetBValue(Color)) > 384 then
    result := clBlack
  else
    result := clWhite;
end;
1

Zła nazwa funkcji. Zmień nazwę bądź implementację ;)

https://stackoverflow.com/a/18142036/1639851

2
robertz68 napisał(a):

No i teraz pytanie - jak rozpoznać czy kolor jest jasny czy ciemny?

Konwertując go na odcień szarości, np. za pomocą takiego wzoru:

Gray := Round((0.299 * R) + (0.587 * G) + (0.114 * B));

Wynikiem jest liczba 8-bitowa – im wyższa wartość, tym jaśniejszy kolor.


Natomiast jeśli chodzi o pozyskanie koloru typowo kontrastowego, to liczbę się xoruje z wartością $FFFFFF, a nie odejmuje/sumuje składowe czy uprawia inne cuda na kiju. Taki sposób wykorzystywany jest m.in. przez systemową funkcję DrawFocusRect, dzięki czemu:

  • rysowana ramka zawsze jest widoczna, nawet na niejednolitym tle,
  • kolejne użycie tej funkcji powoduje ukrycie ramki fokusa, również bez względu na zawartość tła.

Efekt jej działania można obserwować we wszystkich aplikacjach okienkowych, bo służy do uwidaczniania zfokusowanej kontrolki (itemów najróżniejszych list i drzew, przycisków itd.).

1 użytkowników online, w tym zalogowanych: 0, gości: 1