我想展示一些像这个例子的图片

填充颜色由数据库中颜色为十六进制的字段决定(例如:ClassX -> color: #66FFFF)。 现在,我想显示上面的数据与所选的颜色填充(如上图),但我需要知道如果颜色是暗或光,所以我知道如果文字应该在白色或黑色。 有办法吗?谢谢大家


当前回答

我在@SudoPlz提出的高级函数的基础上做了一个函数,它也考虑了浅色和深色:

function getTextColor (bgColor, lightColor = '#FFFFFF', darkColor = '#000000') {

  const getLuminance = function (hexColor) {
    var color = (hexColor.charAt(0) === '#') ? hexColor.substring(1, 7) : hexColor
    var r = parseInt(color.substring(0, 2), 16) // hexToR
    var g = parseInt(color.substring(2, 4), 16) // hexToG
    var b = parseInt(color.substring(4, 6), 16) // hexToB
    var uicolors = [r / 255, g / 255, b / 255]
    var c = uicolors.map(col => col <= 0.03928 ? col / 12.92 : ((col + 0.055) / 1.055) ** 2.4)

    return (0.2126 * c[0]) + (0.7152 * c[1]) + (0.0722 * c[2]);
  }

  var L = getLuminance(bgColor)
  var L1 = getLuminance(lightColor)
  var L2 = getLuminance(darkColor)

  return (L > Math.sqrt((L1 + 0.05) * (L2 + 0.05)) - 0.05) ? darkColor : lightColor;
}

因此,如果深色文本不是黑色而是栗色,灰色背景上的推荐文本颜色会变成白色:

getTextColor('#808080')
"#000000"
getTextColor('#808080', '#FFFFFF', '#800000')
"#FFFFFF"

其他回答

我从来没有做过这样的事情,但是写一个函数来检查每个颜色的值与十六进制7F (FF / 2)的中位数颜色。如果三种颜色中有两种大于7F,那么你正在使用较深的颜色。

用所有24位的颜色测试怎么样?

请注意,YIQ方法将返回1.9:1的最小对比度,这不会通过AA和AAA WCAG2.0测试,假设阈值为128。

对于W3C方法,它将返回最小对比度4.58:1,通过AA和AAA测试的大文本,AA测试的小文本,它不会通过AAA测试的小文本的每一种颜色。

这是马克·兰森的答案的R版本,只使用R基。

hex_bw <- function(hex_code) {

  myrgb <- as.integer(col2rgb(hex_code))

  rgb_conv <- lapply(myrgb, function(x) {
    i <- x / 255
    if (i <= 0.03928) {
      i <- i / 12.92
    } else {
      i <- ((i + 0.055) / 1.055) ^ 2.4
    }
    return(i)
  })

 rgb_calc <- (0.2126*rgb_conv[[1]]) + (0.7152*rgb_conv[[2]]) + (0.0722*rgb_conv[[3]])

 if (rgb_calc > 0.179) return("#000000") else return("#ffffff")

}

> hex_bw("#8FBC8F")
[1] "#000000"
> hex_bw("#7fa5e3")
[1] "#000000"
> hex_bw("#0054de")
[1] "#ffffff"
> hex_bw("#2064d4")
[1] "#ffffff"
> hex_bw("#5387db")
[1] "#000000"

@SoBiT,我在看你的答案,看起来不错,但有一个小错误。你的函数hexToG和hextoB需要一个小的编辑。substr中的最后一个数字是字符串的长度,所以在这种情况下,它应该是“2”,而不是4或6。

function hexToR($h) {
    return hexdec(substr(cutHex($h), 0, 2));
}
function hexToG($h) {
    return hexdec(substr(cutHex($h), 2, 2));
}
function hexToB($h) {
    return hexdec(substr(cutHex($h), 4, 2));
}

除了算术解决方案,还可以使用人工智能神经网络。这样做的好处是,你可以根据自己的口味和需求来定制它。灰白色的文字在明亮的饱和红色上看起来很好,和黑色一样可读)。

下面是一个简洁的Javascript演示,演示了这个概念。你也可以在演示中生成自己的JS公式。

https://harthur.github.io/brain/

下面是一些帮助我解决这个问题的图表。 在第一个图表中,亮度是一个常数128,而色调和饱和度变化。在第二张图中,饱和度是恒定的255,而色调和亮度变化。