根据背景颜色确定字体颜色
给定一个系统(例如网站),让用户自定义某个部分的背景颜色,但不是字体颜色(将选项的数量保持在最低限度),是否有方法通过编程来确定“光源”或“黑暗“的字体颜色是必要的?
我确定有一些算法,但我对颜色,光度等知之甚少,无法自行解决。
我遇到过类似的问题。 我不得不找到一种很好的方法来选择对比字体颜色来在colorscales / heatmaps上显示文本标签。 它必须是通用的方法,生成的颜色必须是“好看的”,这意味着简单的生成互补色并不是好的解决方案 - 有时它会产生难以观察和阅读的奇怪,非常密集的颜色。
经过长时间的测试并试图解决这个问题,我发现最好的解决方案是选择“黑色”颜色的白色字体,“鲜艳”颜色选择黑色字体。
以下是我在C#中使用的函数示例:
Color ContrastColor(Color color)
{
int d = 0;
// Counting the perceptive luminance - human eye favors green color...
double a = 1 - ( 0.299 * color.R + 0.587 * color.G + 0.114 * color.B)/255;
if (a < 0.5)
d = 0; // bright colors - black font
else
d = 255; // dark colors - white font
return Color.FromArgb(d, d, d);
}
这是测试许多不同的颜色(彩虹,灰度,热,冰,和许多其他),是唯一的“通用”的方法,我发现了。
编辑
将计数a
的公式改为“感知亮度” - 它看起来更好! 已经在我的软件中实现了它,看起来不错。
编辑2 @WebSeed提供了这个算法的一个很好的工作示例:http://codepen.io/WebSeed/full/pvgqEq/
谢谢@Gacek。 这里有一个适用于Android的版本:
@ColorInt
public static int getContrastColor(@ColorInt int color) {
// Counting the perceptive luminance - human eye favors green color...
double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
int d;
if (a < 0.5) {
d = 0; // bright colors - black font
} else {
d = 255; // dark colors - white font
}
return Color.rgb(d, d, d);
}
还有一个改进的(更短的)版本:
@ColorInt
public static int getContrastColor(@ColorInt int color) {
// Counting the perceptive luminance - human eye favors green color...
double a = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
return a < 0.5 ? Color.BLACK : Color.WHITE;
}
以防万一有人想要更短,也许更容易理解GaceK的答案版本:
public Color ContrastColor(Color iColor)
{
// Calculate the perceptive luminance (aka luma) - human eye favors green color...
double luma = ((0.299 * iColor.R) + (0.587 * iColor.G) + (0.114 * iColor.B)) / 255;
// Return black for bright colors, white for dark colors
return luma > 0.5 ? Color.Black : Color.White;
}
注意:我删除了亮度值的反转(以使明亮的颜色具有更高的值,这对我来说似乎更自然,并且也是“默认”计算方法。
我从这里使用与GaceK相同的常量,因为它们对我很好。
(您也可以使用以下签名将其作为扩展方法实现:
public static Color ContrastColor(this Color iColor)
然后可以通过foregroundColor = background.ContrastColor()
调用它。)