28

这应该是一个简单的问题,但我一直无法找到使其工作的方法。

本质上,我有一个愚蠢的 localhost 页面,用于我的 web 开发。当我在我们的开发服务器和我的本地版本的 C# 代码(通过主机文件从 dev url 重定向)之间浏览时,我知道有时会忘记“dev.foo.com”指向的内容 - 本地或服务器。

所以我创建了一个页面,它将作为我的默认网页的默认页面在本地运行,因此我可以轻松地从服务器识别我的本地主机。

这个页面随机做了很多事情(包括为 D&D 生成角色的起始统计数据),包括设置随机背景颜色。我通过生成 0 到 255 之间的 3 个随机数来实现这一点,并将它们设置为 CSS 中主体背景颜色的 RGB 值。

给定 3 个整数 R、G 和 B,我如何确定 R2、G2 和 B2 以使第二种颜色与第一种颜色具有高对比度?我喜欢让页面有随机的背景颜色(它让我不习惯登陆页面的外观),但我也喜欢能够阅读文本。

4

10 回答 10

26

您需要不同的亮度才能使文本可读,因为色觉本身的分辨率太低。

因此,作为一种算法,我建议以下内容:

  • 选择一个随机的背景颜色。

  • 然后决定是浅色还是深色。例如,您可以检查三基色的平均值是否大于或等于 128。

  • 对于浅色使用黑色文本,对于深白色文本。

更新:这是我在玩split_evenlyRust crate 示例时制作的示例图像plotters。它显示颜色Palette99

7x3 彩色字段,其索引为黑色或白色,具体取决于背景的亮度

于 2009-01-02T19:45:30.673 回答
8

“对比度”是一个加载词。如果您只关心能够阅读文本,那么一种简单的方法是在 HSL 等基于亮度的颜色空间中工作,并选择亮度差异很大的前景色和背景色。

HSL 和 RGB 之间的转换是众所周知的——有关详细信息,请参阅 Wikipedia。

如果您谈论的是实际的颜色对比度,它几乎没有那么简单(据我所知,有很多感知因素尚未简化为单一颜色空间),但我怀疑你不需要那种复杂程度。

于 2009-01-02T19:35:18.150 回答
5

查看这个 PHP 解决方案:Andreas Gohr用 PHP 计算颜色对比度。当然,它可以移植到任何语言。

他还对他的对比度分析仪进行了很好的演示,您可以在其中找到一些可以使用的最小对比度级别。

于 2009-05-31T20:15:49.480 回答
5

您可以GetBrightness()Color课堂上使用方法。它返回一个从 0.0(黑色亮度)到 1.0(白色)的浮点值。一个简单的解决方案是:

var color1 = new Color.FromArgb(r1, g1, b1);
var brightness = color1.GetBrightness();

var color2 = brightness > 0.5 ? Color.Black : Color.White;
于 2012-03-19T11:20:34.167 回答
3

我在 Palm OS 应用程序中做了类似的事情。这就是我想出的。它不会为您提供“高对比度”颜色,但它会为您提供与文本颜色足够不同的背景颜色,以使其易于阅读:

  // Black background is a special case.  It's fairly likely to occur and 
  // the default color shift we do isn't very noticeable with very dark colors.
  if (backColor.r < 0x20 && backColor.g < 0x20 && backColor.b < 0x20)
  {
      textColor.r = backColor.r + 0x20;
      textColor.g = backColor.g + 0x20;
      textColor.b = backColor.b + 0x20;
  }
  else
  {
      textColor.r = backColor.r + ((backColor.r < 128) ? 0x10 : -0x10);
      textColor.g = backColor.g + ((backColor.g < 128) ? 0x10 : -0x10);
      textColor.b = backColor.b + ((backColor.b < 128) ? 0x10 : -0x10);
  }

您可能不需要将黑色作为特殊情况用于您的目的 - Palm 的颜色处理有点时髦(16 位颜色)。

于 2009-01-02T19:36:34.687 回答
3

这些答案或多或少建议根据颜色是亮还是暗来使用两种或三种颜色中的一种。

我使用了一些不同的方法,在我的情况下它工作得很好。这是实现。

 int color = your_color;
 contrastColor = Color.rgb(255-(color >> 16)&0xFF, 255-(color >> 8)&0xFF, 255- color&0xFF);

它简单而美妙。

于 2018-12-15T03:57:52.390 回答
2

如果你翻转所有位,你会得到“相反”的颜色,这将是一个很好的对比。

我相信它是 C# 中的 ~ 运算符:

R2 = ~R1;
G2 = ~G1;
B2 = ~B1;
于 2009-01-02T19:31:30.297 回答
1

感谢@starblue

这是C#我使用的代码

 public static string GetContrastBlackOrWhiteColorAsHtmlColorCode(Color c)
        {
            System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml("transparent");

            try
            {
                if (c.R >= 128 && c.G >= 128 && c.B >= 128)
                {
                    return System.Drawing.ColorTranslator.ToHtml(Color.Black);
                }
                else
                {
                    return System.Drawing.ColorTranslator.ToHtml(Color.White);
                }
            }
            catch (Exception)
            {
            }

            return System.Drawing.ColorTranslator.ToHtml(color);
        }
于 2014-07-15T19:38:47.160 回答
0

为了获得最佳对比度,请使用此代码

function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){

    $L1 = 0.2126 * pow($R1/255, 2.2) +
          0.7152 * pow($G1/255, 2.2) +
          0.0722 * pow($B1/255, 2.2);

    $L2 = 0.2126 * pow($R2/255, 2.2) +
          0.7152 * pow($G2/255, 2.2) +
          0.0722 * pow($B2/255, 2.2);

    if($L1 > $L2){
        return ($L1+0.05) / ($L2+0.05);
    }else{
        return ($L2+0.05) / ($L1+0.05);
    }
}

function get_the_contrast($c1, $c2) {
    return (lumdiff(hexdec(substr($c1,0,2)),
        hexdec(substr($c1,2,2)),hexdec(substr($c1,4,2)),
        hexdec(substr($c2,0,2)),hexdec(substr($c2,2,2)),
        hexdec(substr($c2,4,2))));
}

上面的方法( AVG(red,green,blue) > 128 )不是很好。

于 2012-12-26T10:42:06.887 回答
0
private Color GetContrastingColor(Color color)
{
    int r = color.R > 0 ? 256 - color.R : 255;
    int g = color.G > 0 ? 256 - color.G : 255;
    int b = color.B > 0 ? 256 - color.B : 255;
    return System.Drawing.Color.FromArgb(r, g, b);
}
于 2013-08-14T22:16:31.770 回答