我想展示一些像这个例子的图片
填充颜色由数据库中颜色为十六进制的字段决定(例如:ClassX -> color: #66FFFF)。 现在,我想显示上面的数据与所选的颜色填充(如上图),但我需要知道如果颜色是暗或光,所以我知道如果文字应该在白色或黑色。 有办法吗?谢谢大家
我想展示一些像这个例子的图片
填充颜色由数据库中颜色为十六进制的字段决定(例如:ClassX -> color: #66FFFF)。 现在,我想显示上面的数据与所选的颜色填充(如上图),但我需要知道如果颜色是暗或光,所以我知道如果文字应该在白色或黑色。 有办法吗?谢谢大家
当前回答
马克的详细回答非常有用。下面是一个javascript实现:
function lum(rgb) {
var lrgb = [];
rgb.forEach(function(c) {
c = c / 255.0;
if (c <= 0.03928) {
c = c / 12.92;
} else {
c = Math.pow((c + 0.055) / 1.055, 2.4);
}
lrgb.push(c);
});
var lum = 0.2126 * lrgb[0] + 0.7152 * lrgb[1] + 0.0722 * lrgb[2];
return (lum > 0.179) ? '#000000' : '#ffffff';
}
然后可以调用这个函数lum([111, 22, 255])来获得白色或黑色。
其他回答
我在@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"
以下是我用Java编写的Android解决方案:
// Put this method in whichever class you deem appropriate
// static or non-static, up to you.
public static int getContrastColor(int colorIntValue) {
int red = Color.red(colorIntValue);
int green = Color.green(colorIntValue);
int blue = Color.blue(colorIntValue);
double lum = (((0.299 * red) + ((0.587 * green) + (0.114 * blue))));
return lum > 186 ? 0xFF000000 : 0xFFFFFFFF;
}
// Usage
// If Color is represented as HEX code:
String colorHex = "#484588";
int color = Color.parseColor(colorHex);
// Or if color is Integer:
int color = 0xFF484588;
// Get White (0xFFFFFFFF) or Black (0xFF000000)
int contrastColor = WhateverClass.getContrastColor(color);
这个(JavaScript代码)怎么样?
/**
* Get color (black/white) depending on bgColor so it would be clearly seen.
* @param bgColor
* @returns {string}
*/
getColorByBgColor(bgColor) {
if (!bgColor) { return ''; }
return (parseInt(bgColor.replace('#', ''), 16) > 0xffffff / 2) ? '#000' : '#fff';
}
下面是我基于Mark的惊人回答编写的Java Swing代码:
public static Color getColorBasedOnBackground(Color background, Color darkColor, Color lightColor) {
// Calculate foreground color based on background (based on https://stackoverflow.com/a/3943023/)
Color color;
double[] cL = new double[3];
double[] colorRGB = new double[] {background.getRed(), background.getGreen(), background.getBlue()};
for (int i = 0; i < colorRGB.length; i++)
cL[i] = (colorRGB[i] / 255.0 <= 0.03928) ? colorRGB[i] / 255.0 / 12.92 :
Math.pow(((colorRGB[i] / 255.0 + 0.055) / 1.055), 2.4);
double L = 0.2126 * cL[0] + 0.7152 * cL[1] + 0.0722 * cL[2];
color = (L > Math.sqrt(1.05 * 0.05) - 0.05) ? darkColor : lightColor;
return color;
}
当使用androidx. composer .ui.graphics. color时,接受的答案在Android上从未工作过。然后我发现在Android Jetpack Compose中实际上有内置的luminance()函数,该函数返回[0,1]之间的亮度值。文档说明:“基于WCAG 2.0中定义的相对亮度公式,W3C推荐标准2008年12月11日。”
以下是官方源代码。
使用示例:
fun Color.generateOnColor()
: Color {
return if (luminance() > 0.5f) {
Color.Black.copy(alpha = .8f)
} else {
Color.White
}
}