给定一个系统(例如一个网站),允许用户自定义某些部分的背景色,但不允许自定义字体颜色(以保持选项的数量最小化),是否有一种方法可以通过编程来确定“浅色”或“深色”字体颜色是必要的?
我相信有一些算法,但我对颜色、光度等了解不够,无法自己找出答案。
给定一个系统(例如一个网站),允许用户自定义某些部分的背景色,但不允许自定义字体颜色(以保持选项的数量最小化),是否有一种方法可以通过编程来确定“浅色”或“深色”字体颜色是必要的?
我相信有一些算法,但我对颜色、光度等了解不够,无法自己找出答案。
当前回答
Swift 4示例:
extension UIColor {
var isLight: Bool {
let components = cgColor.components
let firstComponent = ((components?[0]) ?? 0) * 299
let secondComponent = ((components?[1]) ?? 0) * 587
let thirdComponent = ((components?[2]) ?? 0) * 114
let brightness = (firstComponent + secondComponent + thirdComponent) / 1000
return !(brightness < 0.6)
}
}
更新-发现0.6是一个更好的查询测试平台
其他回答
丑陋的Python,如果你不想写它:)
'''
Input a string without hash sign of RGB hex digits to compute
complementary contrasting color such as for fonts
'''
def contrasting_text_color(hex_str):
(r, g, b) = (hex_str[:2], hex_str[2:4], hex_str[4:])
return '000' if 1 - (int(r, 16) * 0.299 + int(g, 16) * 0.587 + int(b, 16) * 0.114) / 255 < 0.5 else 'fff'
我有同样的问题,但我必须在PHP开发它。我用了@Garek的解决方案,我也用了这个答案: 转换十六进制颜色到RGB值在PHP转换十六进制颜色代码到RGB。
所以我要分享它。
我想在给定的背景颜色下使用这个函数,但不总是从“#”开始。
//So it can be used like this way:
$color = calculateColor('#804040');
echo $color;
//or even this way:
$color = calculateColor('D79C44');
echo '<br/>'.$color;
function calculateColor($bgColor){
//ensure that the color code will not have # in the beginning
$bgColor = str_replace('#','',$bgColor);
//now just add it
$hex = '#'.$bgColor;
list($r, $g, $b) = sscanf($hex, "#%02x%02x%02x");
$color = 1 - ( 0.299 * $r + 0.587 * $g + 0.114 * $b)/255;
if ($color < 0.5)
$color = '#000000'; // bright colors - black font
else
$color = '#ffffff'; // dark colors - white font
return $color;
}
基于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)
然后,您可以轻松地将其称为via foregroundColor = backgroundColor.ContrastColor()。
iOS Swift 3.0 (UIColor扩展):
func isLight() -> Bool
{
if let components = self.cgColor.components, let firstComponentValue = components[0], let secondComponentValue = components[1], let thirdComponentValue = components[2] {
let firstComponent = (firstComponentValue * 299)
let secondComponent = (secondComponentValue * 587)
let thirdComponent = (thirdComponentValue * 114)
let brightness = (firstComponent + secondComponent + thirdComponent) / 1000
if brightness < 0.5
{
return false
}else{
return true
}
}
print("Unable to grab components and determine brightness")
return nil
}
我也遇到过类似的问题。我必须找到一种选择对比字体颜色的好方法,以便在色度/热图上显示文本标签。它必须是通用的方法,生成的颜色必须“好看”,这意味着简单地生成互补色并不是一个好的解决方案——有时它会生成奇怪的、非常强烈的颜色,很难观察和阅读。
经过长时间的测试和尝试解决这个问题,我发现最好的解决方案是选择白色字体的“深色”,和黑色字体的“明亮”的颜色。
下面是我在c#中使用的一个函数示例:
Color ContrastColor(Color color)
{
int d = 0;
// Counting the perceptive luminance - human eye favors green color...
double luminance = (0.299 * color.R + 0.587 * color.G + 0.114 * color.B)/255;
if (luminance > 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/