Как получить обратный цвет любых фоновых изображений
как правильно выбрать цвет, который зависит от фона? если его более темное фоновое изображение, которое автоматически изменит цвет шрифта на более яркие цвета.
возможно ли это? любая идея?
Ответы
Ответ 1
Дэвид обычно работает очень хорошо. Но есть несколько вариантов, и я упомянул некоторые из них. Во-первых, самый наивный подход состоит в том, чтобы сделать
function InvertColor(const Color: TColor): TColor;
begin
result := TColor(Windows.RGB(255 - GetRValue(Color),
255 - GetGValue(Color),
255 - GetBValue(Color)));
end;
но это связано с проблемой # 808080 (почему?). Очень приятным решением является Дэвид, но он выглядит очень плохо для некоторых неудачных цветов фона. Хотя текст, безусловно, видимый, выглядит ужасно. Одним из таких "неудачных" цветов фона является # 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 +, вас может заинтересовать параметр GlowSize
TLabel
.
Ответ 2
Я использую следующее, чтобы дать мне цвет, который контрастирует указанному цвету:
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;
Ответ 3
Я пытаюсь вычислить контраст, основанный на "линейной" цветовой схеме, но на самом деле это не очень хорошо для розовых и голубых цветовых входных значений.
Гораздо лучше рассчитывается на основе формулы 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;
Ответ 4
У меня были проблемы с D6, когда TColor
был clWindow
. Я обнаружил, что если бы я не запускал сначала ColorToRGB(Color)
, GetXValue(Color)
сообщал бы значение R, G, B clWindow
как 5,0,0 соответственно. Что почти черное, а clWindow
было определено как 255 255 255 в моей тестовой среде. Это кажется проблемой только для значений, отправленных с использованием константы, если я отправил в шестнадцатеричном или 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;