代码之家  ›  专栏  ›  技术社区  ›  Jeff

以编程方式选择高对比度颜色

  •  22
  • Jeff  · 技术社区  · 16 年前

    这应该是一个简单的问题,但我还没有找到一种方法让它起作用。

    基本上,我有一个愚蠢的本地主机页面,我在我的Web开发中使用。当我在开发服务器和本地版本的C代码之间冲浪时(通过主机文件从dev url重定向),我有时会忘记dev.foo.com指向本地或服务器。

    所以我创建了一个在本地运行的页面作为我的默认网页的默认页面,这样我就可以很容易地从服务器识别本地主机。

    这个页面做了很多随机的事情(包括为D&D生成一个角色的起始状态),包括设置一个随机的背景色。我通过生成3个介于0和255之间的随机数来实现这一点,并将它们设置为CSS中正文背景色的RGB值。

    给定3个整数r、g和b,如何确定r2、g2和b2,以便第二种颜色与第一种颜色具有高对比度?我喜欢让页面有随机的背景色(这使我不习惯于登录页面的外观),但我也喜欢能够阅读文本。

    11 回复  |  直到 16 年前
        1
  •  21
  •   starblue    16 年前

    要使文本可读,您需要亮度差异,因为颜色视觉本身的分辨率太低。

    作为一种算法,我建议如下:

    • 选取随机背景色。

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

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

        2
  •  6
  •   Tim Lesher    16 年前

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

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

    如果你说的是实际的颜色对比度,它就没有切割和干燥那么简单了(据我所知,有很多感知因素还没有缩小到一个单一的颜色空间),但我怀疑你不需要那种复杂度。

        3
  •  3
  •   GEOCHET S.Lott    15 年前

    查看此PHP解决方案: Calculating Color Contrast with PHP 安德烈亚斯·高尔。当然,它可以移植到任何语言。

    他也有一个非常好的对比度分析仪演示,在那里你可以找到一些最低的对比度水平来工作。

        4
  •  2
  •   Marko Juvančič    10 年前

    你可以使用方法 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;
    
        5
  •  1
  •   mhenry1384    16 年前

    我在PalmOS应用程序中做了类似的事情。这就是我想到的。它不会给你“高对比度”的颜色,但它会给你一个与文本颜色足够不同的背景颜色,使你能够很好地阅读:

      // 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位颜色)。

        6
  •  1
  •   Michael Bray    16 年前
        7
  •  1
  •   Mayank Kumar Chaudhari    6 年前

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

    我使用了一种不同的方法,它在我的案例中工作得很好。这是实现。

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

    它简单而美妙。

        8
  •  0
  •   bobwienholt    16 年前

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

    我相信是C中的诳接线员:

    R2 = ~R1;
    G2 = ~G1;
    B2 = ~B1;
    
        9
  •  0
  •   user604234    12 年前

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

    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(红、绿、蓝)>128)不是很好。

        10
  •  0
  •   jco    11 年前
    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);
    }
    
        11
  •  0
  •   NoWar    10 年前

    多亏了 星蓝 !

    这里是 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);
            }