根据背景使前景色为黑色或白色

时间:2010-02-11 00:35:21

标签: c# colors

计算rgb组件的平均值然后决定是使用黑色还是白色?

我是否必须在第一步将RGB转换为HSV'因为RGB并不总是人眼看到的?

我正在使用C#

5 个答案:

答案 0 :(得分:66)

事实上我不久前需要这个功能用于项目。

private int PerceivedBrightness(Color c)
{
    return (int)Math.Sqrt(
    c.R * c.R * .241 +
    c.G * c.G * .691 +
    c.B * c.B * .068);
}

我在Nbd Tech网站上发现的这个公式涉及感知颜色和颜色转换公式。该网站提供了大量有用的信息。

以下是如何使用它来选择黑色或白色:

var foreColor = (PerceivedBrightness(backColor) > 130 ? Color.Black : Color.White);

您可以使用130以外的值作为截止值;这是偏好。


更新:根据Darel Rex Finley在his site的说法:

  

我通过使用Photoshop来实现的值实际上是.241,.691和.068,但我已经被告知值.299,.587和.114更准确。

本规范遵循ITU-R Recommendation BT.601(或简称601)。我上面提到的网站Nbd Tech尚未更新以反映这一点。

基于此,这里是更新的方法(感谢DTI-Matt的评论)

private int PerceivedBrightness(Color c)
{
    return (int)Math.Sqrt(
    c.R * c.R * .299 +
    c.G * c.G * .587 +
    c.B * c.B * .114);
}

关于门槛偏好的说明:

在中间附近感知亮度的颜色(例如120-140)将更主观。例如,评估为139的红色(FF0000)是否更清晰,黑色或白色覆盖是否值得商榷。

White and Black on Red

答案 1 :(得分:6)

那怎么样?

private static Color GetReadableForeColor(Color c)
{
    return (((c.R + c.B + c.G) / 3) > 128) ? Color.Black : Color.White;
}

答案 2 :(得分:5)

Color结构支持本地转换为HSB。

if (Color.GetBrightness() > 0.5f) {
  // win
}

您可能还想添加饱和度分量,考虑到饱和度也会导致明显的“亮度”。

答案 3 :(得分:0)

你可以根据颜色深度做一个简单的计算,如果你有一个#FFFFFF颜色格式,你可以添加RGB值并计算它们是否在中途。

在这种情况下,最大值为255(F x F = 256),所以只需检查它是否低于该阈值:

var colorCode = ((R + B + G) < 255*3) ? "#FFFFFF" : "#000000";

如果颜色在下方,则颜色较暗......使用白色背景。如果它在上面,它更轻......使用黑色背景。这不是完美的,而是一个开始的想法。

答案 4 :(得分:-1)

如果我理解正确,一种方法可能是掌握桌面壁纸图片,检查一些庄园是什么颜色,然后根据它改变你的应用颜色。

有一篇文章on geekpedia关于掌握当前的桌面壁纸(以及谷歌上的大量点击),但基本前提是获取当前壁纸的注册表值:

RegistryKey rkWallPaper = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", false);
string WallpaperPath = rkWallPaper.GetValue("WallPaper").ToString();

然后您可以使用该路径打开图像。然后,您可以获得许多属性,例如RGB中的尺寸和单个像素颜色。

要弄清楚它是“更白”还是“更黑”,你有很多选择。

一个想法是获取RGB中的每个像素颜色,平均值(获得灰度值),然后平均图像上每个像素的灰度值。如果出现这种情况> 128然后它可以被认为是“白色”。如果&lt; 128然后“黑”。基本上,您决定图像像素强度平均到中灰色分界线的哪一侧。

// Psudo code - can't check the C# spec atm.
foreach(Pixel p in image)
{
    // get average of colour components.
    double greyScale = (p.Red + p.Green + p.Blue) / 3;
    totalIntensity += greyScale;
}

double averageImageIntensity = totalIntensity / image.NumPixels;

if(totalIntensity > 128) // image could be considered to be "white"
else // image could be considered "black".

问题:可能是一个缓慢的过程,您可能只想采样一些像素(例如,每10个像素等)以节省时间。更一般地说,做起来似乎是一件非常讨厌的事情。在运行时提取用户文件并弄乱它们并不是很干净,它提供了潜在的安全性和稳定性问题。如果图像是duff或腐败等怎么办?

我个人建议只是让用户自己选择颜色/主题/皮肤,或者更好,让他们自定义它!

相关问题