如何检查十六进制颜色是否为“”;太黑”;
How to check if hex color is "too black"?
我正试图评估颜色选择器选择的颜色的暗度,看看它是否是"太黑";,如果是,请将其设置为白色。我想我可以用十六进制值的第一个字符来实现这一点;"轻";颜色也一样。
我有以下代码:
if (lightcolor.substring(0, 3) == "#00" || lightcolor.substring(0, 3) == "#010") {
lightcolor = "#FFFFFF";
color = lightcolor;
}
必须有一种更有效的十六进制数学方法来知道一种颜色已经超过了一定的黑暗程度?如同如果CCD_ 1+";某个十六进制值";CCD_ 2";某个十六进制值";然后将其设置为CCD_ 3。
我添加了tinyColor
,这可能对此有用,但我不确定。
您必须分别提取三个RGB分量,然后使用标准公式将生成的RGB值转换为其感知亮度。
假设六个字符的颜色:
var c = c.substring(1); // strip #
var rgb = parseInt(c, 16); // convert rrggbb to decimal
var r = (rgb >> 16) & 0xff; // extract red
var g = (rgb >> 8) & 0xff; // extract green
var b = (rgb >> 0) & 0xff; // extract blue
var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
if (luma < 40) {
// pick a different colour
}
编辑
自2014年5月以来,tinycolor
现在具有getBrightness()
功能,尽管使用了CCIR601加权因子而不是上面的ITU-R加权因子。
编辑
得到的亮度值范围是0..255,其中0是最暗的,255是最亮的。大于128的值被tinycolor
认为是轻的。(无耻地从@pau.moreno和@Alnitak的评论中复制)
我发现了这个WooCommerce Wordpress PHP函数(wc_hex_is_light),并将其转换为JavaScript。工作正常!
function wc_hex_is_light(color) {
const hex = color.replace('#', '');
const c_r = parseInt(hex.substr(0, 2), 16);
const c_g = parseInt(hex.substr(2, 2), 16);
const c_b = parseInt(hex.substr(4, 2), 16);
const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
return brightness > 155;
}
@Sliffcak,感谢您的评论。。。使用substring
,因为substr
已弃用:
function wc_hex_is_light(color) {
const hex = color.replace('#', '');
const c_r = parseInt(hex.substring(0, 0 + 2), 16);
const c_g = parseInt(hex.substring(2, 2 + 2), 16);
const c_b = parseInt(hex.substring(4, 4 + 2), 16);
const brightness = ((c_r * 299) + (c_g * 587) + (c_b * 114)) / 1000;
return brightness > 155;
}
TinyColor库(您已经提到过它)提供了几个用于检查和操作颜色的功能,其中包括:
-
获取亮度
返回由Web内容可访问性指南(1.0版)定义的颜色的感知亮度,范围为0-255。
tinycolor("#fff").getBrightness(); // 255
-
isLight
返回一个布尔值,指示颜色的感知亮度是否为浅色。
tinycolor("#fff").isLight(); // true tinycolor("#000").isLight(); // false
-
isDark
返回一个布尔值,指示颜色的感知亮度是否为暗。
tinycolor("#fff").isDark(); // false tinycolor("#000").isDark(); // true
-
getLuminance
返回一种颜色的感知亮度,根据Web内容可访问性指南(2.0版)的定义,从0-1开始。
tinycolor("#fff").getLuminance(); // 1
这适用于十六进制,例如#fefefe
function isTooDark(hexcolor){
var r = parseInt(hexcolor.substr(1,2),16);
var g = parseInt(hexcolor.substr(3,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
// Return new color if to dark, else return the original
return (yiq < 40) ? '#2980b9' : hexcolor;
}
您可以通过更改将其更改为返回lightcolor
0或false
return (yiq < 40) ? '#2980b9' : hexcolor;
至
return (yiq < 40);
亮度和亮度之间有一个重要的区别。亮度,在一天结束时,是衡量有多少能量穿过某个区域的指标,完全忽略了我们的感知系统是如何感知这种能量的。另一方面,亮度是衡量我们如何感知能量的指标,并考虑到亮度和我们的感知系统之间的关系。(令人困惑的是,有一个术语叫相对亮度,它似乎与亮度术语同义。这让我很困惑)。
准确地说,正如其他人所建议的那样,你正在寻找"亮度"、"值"或"相对亮度"。你可以用几种不同的方式来计算(这就是人类!)http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
- 取R、G和B的最大值
- 取R、G和B的最大值和最小值的平均值
- 取三者的平均值
- 使用一些加权平均值,正如其他人在这里建议的那样
您可以计算亮度:
因此,亮度是表面亮度的指标。
因此,选择文本是白色还是黑色是很好的。
var getRGB = function(b){
var a;
if(b&&b.constructor==Array&&b.length==3)return b;
if(a=/rgb'('s*([0-9]{1,3})'s*,'s*([0-9]{1,3})'s*,'s*([0-9]{1,3})'s*')/.exec(b))return[parseInt(a[1]),parseInt(a[2]),parseInt(a[3])];
if(a=/rgb'('s*([0-9]+(?:'.[0-9]+)?)'%'s*,'s*([0-9]+(?:'.[0-9]+)?)'%'s*,'s*([0-9]+(?:'.[0-9]+)?)'%'s*')/.exec(b))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];
if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],
16)];
if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];
return (typeof (colors) != "undefined")?colors[jQuery.trim(b).toLowerCase()]:null
};
var luminance_get = function(color) {
var rgb = getRGB(color);
if (!rgb) return null;
return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
}
上面的方法允许您以不同的格式传递颜色,但算法基本上只是在luminance_get
中。
当我使用它时,如果亮度大于180
,我将颜色设置为黑色,否则设置为白色。
我意识到这段对话已经有几年的历史了,但它仍然是相关的。我想补充一点,我的团队在Java(SWT)中也遇到了同样的问题,并发现这更准确:
private Color getFontColor(RGB bgColor) {
Color COLOR_BLACK = new Color(Display.getDefault(), 0, 0, 0);
Color COLOR_WHITE = new Color(Display.getDefault(), 255, 255, 255);
double luminance = Math.sqrt(0.241
* Math.pow(bgColor.red, 2) + 0.691 * Math.pow(bgColor.green, 2) + 0.068
* Math.pow(bgColor.blue, 2));
if (luminance >= 130) {
return COLOR_BLACK;
} else {
return COLOR_WHITE;
}
}
一个可能的解决方案是将颜色从RGB转换为HSB。HSB代表色调、饱和度和亮度(也称为HSV,其中V表示值)。然后你只需要检查一个参数:亮度。
我结合了下面@Alnitak和@SergioCabral的答案。我还实现了一个适用于标准和简短表单的十六进制值解析器。
const hexToRgb = (hex) =>
(value =>
value.length === 3
? value.split('').map(c => parseInt(c.repeat(2), 16))
: value.match(/.{1,2}/g).map(v => parseInt(v, 16)))
(hex.replace('#', ''));
// Luma - https://stackoverflow.com/a/12043228/1762224
const isHexTooDark = (hexColor) =>
(([r, g, b]) =>
(0.2126 * r + 0.7152 * g + 0.0722 * b) < 40)
(hexToRgb(hexColor));
// Brightness - https://stackoverflow.com/a/51567564/1762224
const isHexTooLight = (hexColor) =>
(([r, g, b]) =>
(((r * 299) + (g * 587) + (b * 114)) / 1000) > 155)
(hexToRgb(hexColor));
console.log(isHexTooDark('#222')); // true
console.log(isHexTooLight('#DDD')); // true
- 如何更改文本区域的颜色's文本,具体取决于它是否为占位符
- 如何检查十六进制颜色是否为“”;太黑”;
- 是否可以根据FullCalendar事件的标题指定其背景颜色
- 是否可以添加图像作为徽标颜色框
- 根据是否选择了文件来更改文件上传时的边框颜色
- 查看整个画布是否被涂成一种颜色的方法.Javascript + processing.js
- 是否可以使用 css 和 javascript 将颜色从深色变成浅色
- 当 y 轴反转时是否可以保持填充颜色
- 如何找出某些内容是否是HTML颜色名称之一,而无需检查每个颜色名称
- 如何检查某个类是否有背景颜色,如果有,请更改背景颜色
- 是否可以在每次单击按钮时更改背景颜色并恢复为纯JavaScript中的原始颜色
- 是否可以禁用颜色框图像上的单击侦听器
- 是否可以替换输入字段中每个字符的颜色
- 使用jquery检查两种颜色是否接触
- 检查用户是否在浏览器中设置了自定义颜色
- 是否可以使用Javascript在页面刷新时随机生成预先确定的链接颜色和悬停颜色
- 是否可以创建一个具有多种颜色和字体大小的paper.js PointText对象
- 检查所有输入文本是否为空,如果至少有一个已填充,则打开颜色框
- 是否可以在一个jquery字符串中使用两种颜色的字体
- 在Javascript Regex中,如何验证字符串是否为有效的十六进制颜色