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

Random 以编程方式选择高对比度颜色,random,colors,rgb,Random,Colors,Rgb,这应该是一个简单的问题,但我还没有找到一个方法让它工作 本质上,我有一个愚蠢的localhost页面,我在我的web开发中使用它。当我在开发服务器和本地版本的C#代码(通过主机文件从开发url重定向)之间浏览时,我有时会忘记“dev.foo.com”在本地或服务器上的含义 因此,我创建了一个在本地运行的页面,作为默认web页面的默认页面,因此我可以轻松地从服务器中识别本地主机 这个页面随机地做很多事情(包括为D&D生成一个角色的起始统计数据),包括设置一个随机的背景颜色。我通过生成3个介于0和2

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

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

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

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


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

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

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

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

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


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

我在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);
  }
//黑色背景是一种特殊情况。这很可能发生,而且
//我们所做的默认颜色偏移对于非常暗的颜色不是很明显。
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;
}
其他的
{
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位颜色)。

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

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

  • 选择一个随机的背景色

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

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

更新:这是我在玩
均匀分割时拍摄的一张示例图像
铁锈板条箱
绘图仪的示例
。它显示
调色板99
中的颜色:


查看这个PHP解决方案:由Andreas Gohr编写。当然,它可以移植到任何语言


他还有一个非常好的对比度分析器演示,您可以在其中找到一些最小的对比度级别。

您可以在
Color
类中使用方法
GetBrightness()
。它返回从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;

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

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))));
}

上面的方法(平均值(红、绿、蓝)>128)不是很好。

多亏了@starblue

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);
}
下面是我使用的
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);
        }

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

我使用了一种有点不同的方法,在我的案例中效果很好。下面是实现

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

这很简单,也很好。

对于颜色直方图“中间”附近的颜色,例如#808080,这不太合适。这是真的。。。但是相反的颜色在放在一起的时候有一个额外的好处,那就是看起来很悦目。蒂姆,你可以说得更强烈一点,它根本不起作用。:-)您可以添加一些“if”语句,用于不能正常工作的“中间”情况。您也可以使用类似“if(light)return Black;else return White”的内容,但这显然会减少输出颜色的数量。也许我应该指出这是一个ASP站点,但您的评论仍然很有用。我唯一的问题是中间的那些“边缘”案例,接下来的问题是“在切换到黑白之前离中心有多近?”这是一个相当简单的解决方案,而且(现在)效果相当好。我将尝试一下,因为它总是可读的,如果有点简单。有一个类处理HSL转换,可以在这里找到,实际上,只有第三个函数处理颜色对比度,第一个和第二个正在计算一些随机度量值可能是对您的解决方案的简短评论将有助于操作更多。这不适用于值在128左右的中档颜色,最好这样做,这与StarBlue所说的不完全相同-他建议平均R、G和B值。您正在设置最小阈值。您的代码将使用白色,甚至在,并且Hi Mayank刚刚发送了一封电子邮件,如果您感兴趣,关于潜在的咨询工作!我认为这是相同的方法:Color.rgb(255-Color.red(Color
 int color = your_color;
 contrastColor = Color.rgb(255-(color >> 16)&0xFF, 255-(color >> 8)&0xFF, 255- color&0xFF);