给定背景颜色,如何获得使其在背景颜色上可读的前景色?

时间:2010-06-25 07:26:04

标签: user-interface colors

鉴于背景颜色,如何获得使其在背景颜色上可读的前景色?

我的意思是在程序中自动计算前景色。

或简化问题,如果从白/黑中选择前景色,如何在程序中进行选择?

8 个答案:

答案 0 :(得分:18)

最安全的做法是遵守万维网联盟(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常量(四舍五入到4位)组合它们:

Y = 0.2126 * r + 0.7151 * g + 0.0721 * b

这使得白色Y为1,黑色Y为0,因此最大可能对比度为(1.05 / 0.05)= 21(在舍入误差范围内)。

let JuicyStudio do the math为你。

此计算假设在相对昏暗的房间(或者如果用户必须使用,则用户可以调暗的房间)中执行标准的监视器。这使它足以满足家庭或办公室的使用,但我不知道它是否适用于移动应用程序或户外使用的其他设备。

答案 1 :(得分:7)

这是我在Java和Javascript中所做的一个。它在javascript中松散地基于this一个。我从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;
    }

}

enter image description here

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";
}

答案 2 :(得分:5)

  • 计算亮度(参见HSL
  • 如果亮度低于50%,请使用白色。否则,请使用黑色。

使用颜色作为前景色很困难,因为您必须考虑对比度和色盲。

答案 3 :(得分:1)

这里有一些实际的(红宝石)代码,它们实际上会解除这些:

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"

答案 4 :(得分:0)

你可以计算反色,但你会冒着对比度在色彩空间“中间”缩小的风险。

答案 5 :(得分:0)

万一这仍然对某人有用,这是基于上述答案的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);
}

答案 6 :(得分:0)

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;

答案 7 :(得分:0)

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()