Question

how to get the right color automatically that is depending on the background? if its darker background image, that will automatically change the font color into brighter colors. was it possible? any idea?

Was it helpful?

Solution

David's answer is generally working very well. But there are a few options, and I will mention some of them. First, the very most naïve approach, is to do

function InvertColor(const Color: TColor): TColor;
begin
    result := TColor(Windows.RGB(255 - GetRValue(Color),
                                 255 - GetGValue(Color),
                                 255 - GetBValue(Color)));
end;

but this suffers from the #808080 problem (why?). A very nice solution is David's, but it looks very bad for some unfortunate background colours. Although the text is certainly visible, it looks horrible. One such "unfortunate" background colour is #008080.

Usually I prefer the text to be black if the background is "light", and white if the background is "dark". I thus do

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

Also, if you are using Delphi 2009+ and targeting Windows Vista+, you might be interested in the GlowSize parameter of the TLabel.

OTHER TIPS

I use the following to give me a color that contrasts the specified color:

function xorColor(BackgroundColor: TColor): TColor;
begin
  BackgroundColor := ColorToRGB(BackgroundColor);
  Result := RGB(
    IfThen(GetRValue(BackgroundColor)>$40, $00, $FF),
    IfThen(GetGValue(BackgroundColor)>$40, $00, $FF),
    IfThen(GetBValue(BackgroundColor)>$40, $00, $FF)
  );
end;

I try compute contrast based on "linear" color scheme, but it is really not good on pink and cyan color input values. Much better it is calculate based on RGB formula:

brightness = sqrt( .241 * R^2 + .691 * G^2 + .068 * B^2 ) 

In Delphi i create this subroutine:

function GetContrastingColor(Color: TColor): TColor;
var r,g,b:double;i:integer;
begin
Color := ColorToRGB(Color);
r:=GetRValue(Color) ;
g:=GetGValue(Color) ;
b:=GetBValue(Color) ;
i:=round( Sqrt(
      r * r * 0.241 +
      g * g * 0.691 +
      b * b * 0.068));
if (i > 128) then   // treshold seems good in wide range
  Result := clBlack
else
  Result := clWhite;
end;

I had issues with D6, when the TColor was clWindow. I discovered that if I did not first run ColorToRGB(Color), GetXValue(Color) would report the R,G,B value of clWindow as 5,0,0 respectively. Which is nearly black, while clWindow was defined as 255,255,255 on my test environment. This seems to only be a problem for values sent in using the constant, if I sent in the hex or int equivalents it worked fine.

function InvertColor(const Color: TColor): TColor;
begin
  if (GetRValue(ColorToRGB(Color)) +
      GetGValue(ColorToRGB(Color)) +
      GetBValue(ColorToRGB(Color)))/3 > 128 then
    result := clBlack //color is light
  else
    result := clWhite; //color is dark
end;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top