【发布时间】:2011-03-08 04:08:54
【问题描述】:
给定背景色,如何获得使其在该背景色上可读的前景色?
我的意思是在程序中自动计算前景色。
或者简化问题,如果前景色从白/黑中选择,在程序中如何选择?
【问题讨论】:
标签: user-interface colors
给定背景色,如何获得使其在该背景色上可读的前景色?
我的意思是在程序中自动计算前景色。
或者简化问题,如果前景色从白/黑中选择,在程序中如何选择?
【问题讨论】:
标签: user-interface colors
根据上面的答案,我想出了一个 C# 实现,您可能希望根据您的要求调整 alpha 的逻辑。
public static class ColorExtension
{
public static Color GetReadableColor(this Color color) => color.GetLuminance() > 140 || color.A != 255 ? Color.Black : Color.White;
public static double GetLuminance(this Color color) => (0.2126 * color.R) + (0.7151 * color.G) + (0.0721 * color.B);
}
【讨论】:
PyQt5 版本 Michael Zuschlag 的回答:
import sys
from PyQt5.QtGui import QColor
class MostReadableColor():
def getLuminance(self, color):
""" get color luminance.
Convert color RGB values to gamma adjusted normalized rgb values
then combine them using sRGB constants (rounded to 4 places).
"""
r, g, b, a = QColor(color).getRgb()
l = ((r/255)**2.2)*0.2126 + ((g/255)**2.2)*0.7151 + \
((b/255)**2.2)*0.0721
return(l)
def getContrastRation(self, color1, color2):
l1 = self.getLuminance(color1)
l2 = self.getLuminance(color2)
cr = (l1 + .05)/(l2+.05) if l1 > l2 else (l2+.05)/(l1 + .05)
return(cr)
def getMostReadable(self, color):
cr = []
for c in QColor.colorNames():
if c == 'transparent':
continue
cr.append([self.getContrastRation(color, c), c])
sorted_cr = sorted(cr, reverse=True)
return(sorted_cr[0][1])
def main():
if len(sys.argv) != 2:
print("usage: MostReadableColor color_name (ex: 'red')")
else:
mrc = MostReadableColor()
best_contrast_color = mrc.getMostReadable(sys.argv[1])
print(f"{best_contrast_color}")
if __name__ == "__main__":
main()
【讨论】:
Pascal / Delphi 版本:
var
red,green,blue : Integer;
luminance : double;
// convert hexa-decimal values to RGB
red := (_BackgroundColor) and $FF;
green := (_BackgroundColor shr 8) and $FF;
blue := (_BackgroundColor shr 16) and $FF;
luminance := (0.2126 * red) + (0.7152 * green) + (0.0722 * blue);
if luminance < 140 then
Result := TColors.White
else
Result := TColors.Black;
【讨论】:
如果这仍然对某人有用,这是基于上述答案的 Dart 实现
Color getInverseBW(Color color) {
double luminance = (0.2126 * color.red + 0.7152 * color.green + 0.0722 * color.blue);
return (luminance < 140) ? Color(0xffffffff) : Color(0xff000000);
}
【讨论】:
这是我在 Java 和 Javascript 中都做过的一个。它松散地基于this javascript 中的一个。我从here 中获取了亮度公式。我眼中的阈值甜蜜点约为 140。
Java 版本:
public class Color {
private float CalculateLuminance(ArrayList<Integer> rgb){
return (float) (0.2126*rgb.get(0) + 0.7152*rgb.get(1) + 0.0722*rgb.get(2));
}
private ArrayList<Integer> HexToRBG(String colorStr) {
ArrayList<Integer> rbg = new ArrayList<Integer>();
rbg.add(Integer.valueOf( colorStr.substring( 1, 3 ), 16 ));
rbg.add(Integer.valueOf( colorStr.substring( 3, 5 ), 16 ));
rbg.add(Integer.valueOf( colorStr.substring( 5, 7 ), 16 ));
return rbg;
}
public String getInverseBW(String hex_color) {
float luminance = this.CalculateLuminance(this.HexToRBG(hex_color));
String inverse = (luminance < 140) ? "#fff" : "#000";
return inverse;
}
}
Javascript 版本:
在 javascript 中,前端的东西也是一样的。 RGB转换取自here:
hex_to_rgb: function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
},
hex_inverse_bw: function(hex) {
rgb = this.hex_to_rgb(hex);
luminance = (0.2126*rgb["r"] + 0.7152*rgb["g"] + 0.0722*rgb["b"]);
return (luminance < 140) ? "#ffffff": "#000000";
}
【讨论】:
这里有一些实际的 (ruby) 代码可以真正完成提升:
rgbval = "8A23C0".hex
r = rgbval >> 16
g = (rgbval & 65280) >> 8
b = rgbval & 255
brightness = r*0.299 + g*0.587 + b*0.114
return (brightness > 160) ? "#000" : "#fff"
【讨论】:
最安全的选择是遵守万维网联盟 (W3C) 的 Web 内容可访问性指南 2.0,该指南指定了亮度 contrast ratio of 4.5:1 for regular text (12 pt or smaller), and 3.0:1 for large text。对比度定义为:
[Y(b) + 0.05] / [Y(d) + 0.05]
其中 Y(b) 是较亮颜色的亮度(亮度),Y(d) 是较暗颜色的亮度。
您首先将每种颜色的 RGB 值转换为经过伽马调整的归一化 rgb 值,从而计算亮度 Y:
然后使用 sRGB 常量组合它们(四舍五入):
Y = 0.2126*r + 0.7151*g + 0.0721*b
这使白色的 Y 为 1,黑色的 Y 为 0,因此可能的最大对比度为 (1.05/ 0.05) = 21(在舍入误差内)。
或者let JuicyStudio do the math给你。
此计算假设在相对昏暗的房间(或用户可以根据需要调暗的房间)中的标准性能监视器。这足以满足家庭或办公室使用,但我不知道它是否适合移动应用程序或其他户外使用的设备。
【讨论】:
您可以计算反色,但您会冒着在颜色空间的“中间”降低对比度的风险。
【讨论】:
使用颜色作为前景色很困难,因为您必须考虑对比度和色盲。
【讨论】: