如何获得任何背景图像的相反颜色

时间:2010-12-13 15:48:11

标签: delphi image color-picker

如何根据背景自动获得正确的颜色?如果它的背景图像较暗,则会自动将字体颜色更改为更亮的颜色。 有可能吗?任何想法?

4 个答案:

答案 0 :(得分:24)

大卫的回答一般都很顺利。但是有一些选择,我会提到其中的一些。首先,最天真的方法是做

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的{​​{1}}参数感兴趣。

答案 1 :(得分:11)

我使用以下内容给我一种与指定颜色形成鲜明对比的颜色:

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;

答案 2 :(得分:1)

我尝试基于“线性”颜色方案计算对比度,但在粉红色和青色颜色输入值上实际上并不好。 更好的是根据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;

答案 3 :(得分:0)

TColorclWindow时,我遇到了D6的问题。我发现如果我没有先运行ColorToRGB(Color)GetXValue(Color)会将clWindow的R,G,B值分别报告为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;