как получить противоположный цвет любых фоновых изображений

Как получить правильный цвет автоматически, в зависимости от фона? если его темное фоновое изображение, это автоматически изменит цвет шрифта на более яркие цвета. возможно ли это? есть идеи?

4 ответов


ответ Дэвида, как правило, работает очень хорошо. Но есть несколько вариантов, и я упомяну некоторые из них. Во-первых, самый наивный подход-это сделать

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

но это страдает от проблемы #808080 (почему?). Очень хорошим решением является David, но это выглядит очень плохо для некоторых неудачных цветов фона. Хотя текст, конечно, виден, он выглядит ужасно. Один из таких "неудачных" цветов фона - #008080.

обычно я предпочитаю, чтобы текст был черный, если фон "светлый", и белый, если фон"темный". Я так делаю

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

кроме того, если вы используете Delphi 2009+ и ориентируетесь на Windows Vista+, вас может заинтересовать


Я использую следующее, чтобы дать мне цвет, который контрастирует с указанным цветом:

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

Я пытаюсь вычислить контраст на основе "линейной" цветовой схемы, но это действительно не хорошо на входных значениях розового и голубого цветов. Гораздо лучше это вычислить на основе формулы RGB:

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

в Delphi я создаю эту подпрограмму:

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;

у меня были проблемы с D6, когда TColor был clWindow. Я обнаружил, что если я сначала не побегу ColorToRGB(Color), GetXValue(Color) сообщит значение R,G,B clWindow как 5,0,0 соответственно. Который почти черный, в то время как clWindow был определен как 255,255,255 в моей тестовой среде. Кажется, это проблема только для значений, отправленных с использованием константы, если я отправил эквиваленты hex или int, он работал нормально.

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;