给定背景颜色,如何获得使其在该背景颜色上可读的前景色?
Posted
技术标签:
【中文标题】给定背景颜色,如何获得使其在该背景颜色上可读的前景色?【英文标题】:Given a background color, how to get a foreground color that makes it readable on that background color? 【发布时间】:2011-03-08 04:08:54 【问题描述】:给定背景色,如何获得使其在该背景色上可读的前景色?
我的意思是在程序中自动计算前景色。
或者简化问题,如果前景色从白/黑中选择,在程序中如何选择?
【问题讨论】:
重复:***.com/questions/946544/… 相关但也重复:***.com/questions/2241447/…***.com/questions/3942878/… 【参考方案1】:根据上面的答案,我想出了一个 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);
【讨论】:
【参考方案2】: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()
【讨论】:
【参考方案3】: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;
【讨论】:
【参考方案4】:如果这仍然对某人有用,这是基于上述答案的 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);
【讨论】:
【参考方案5】:这是我在 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";
【讨论】:
谢谢,正是我需要的。其他问题中的另一种解决方案和这个问题的公认答案,在计算光度之前对 rgb 进行归一化对我不起作用,但这是完美的。 感谢您提供即用型代码!欣赏!【参考方案6】:这里有一些实际的 (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"
【讨论】:
【参考方案7】:最安全的选择是遵守万维网联盟 (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:
r = (R/255)^2.2 b = (B/255)^2.2 g = (G/255)^2.2然后使用 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给你。
此计算假设在相对昏暗的房间(或用户可以根据需要调暗的房间)中的标准性能监视器。这足以满足家庭或办公室使用,但我不知道它是否适合移动应用程序或其他户外使用的设备。
【讨论】:
【参考方案8】:您可以计算反色,但您会冒着在颜色空间的“中间”降低对比度的风险。
【讨论】:
【参考方案9】: 计算亮度(参见HSL) 如果亮度低于 50%,请使用白色。否则,请使用黑色。使用颜色作为前景色很困难,因为您必须考虑对比度和色盲。
【讨论】:
我看了一些rgb_to_hsl的sn-p代码,亮度是用MAX(r, g, b)/255计算的,好像还不够选择。 太棒了。 d3.rgb().hsl 很简单以上是关于给定背景颜色,如何获得使其在该背景颜色上可读的前景色?的主要内容,如果未能解决你的问题,请参考以下文章
Qt5:如何改变表格中一行的背景颜色,使其在排序时自动移动?