Как проверить, является ли "черный цвет" шестнадцатеричного цвета?
Я пытаюсь оценить темноту цвета, выбранного цветовым подборщиком, чтобы увидеть, слишком ли она "черная", и если да, установите ее в белый цвет. Я думал, что могу использовать первые символы шестнадцатеричного значения, чтобы снять это. Он работает, но он также переключает некоторые законно "светлые" цвета.
У меня есть код:
if (lightcolor.substring(0,3) == "#00"|| lightcolor.substring(0,3) == "#010"){
lightcolor="#FFFFFF";
color=lightcolor;
}
Должен быть более эффективный способ с шестнадцатеричной математикой знать, что цвет вышел за пределы определенного уровня темноты? Например, если lightcolor + "some hex value" <= "some hex value", то установите его в белый цвет.
У меня есть tinyColor, который может быть полезен для этого, но я не знаю точно.
Связка!
Ответы
Ответ 1
Вам нужно извлечь три компонента 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 года tinycolor
теперь имеет функцию getBrightness()
, хотя и использует весовые коэффициенты CCIR601 вместо вышеперечисленных ITU-R.
Ответ 2
Библиотека TinyColor (вы уже упомянули об этом) предоставляет несколько функций для проверки и управления цветами, среди которых:
Ответ 3
Вы можете вычислить luminance:
Таким образом, яркость является индикатором того, насколько яркой будет поверхность.
Так здорово выбрать, должен ли текст быть белым или черным.
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
, в противном случае - белый.
Ответ 4
Здесь важное различие между яркостью и яркостью. Яркость, в конце дня, является мерой того, сколько энергии проходит через определенную область и полностью игнорирует то, как наши воспринимающие системы воспринимают эту энергию. Яркость, с другой стороны, является мерой того, как мы воспринимаем эту энергию и учитываем связь между яркостью и нашей системой восприятия. (Как точка смятения, есть термин, называемый относительной яркостью, который, по-видимому, используется синонимом с терминами яркости. Это сотрясало меня хорошо).
Чтобы быть точным, вы ищете "яркость" или "значение" или "относительную яркость", как предложили другие. Вы можете рассчитать это несколькими способами (например, быть человеком!) http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
- Возьмите максимум R, G и B.
- Возьмите среднее значение max и min из R, G и B.
- Возьмите среднее значение для всех трех.
- Используйте средневзвешенное значение, которое предложили другие.
Ответ 5
Возможным решением было бы преобразовать ваш цвет из RGB в HSB. HSB обозначает оттенок, насыщенность и яркость (также известный как HSV, где V - значение). Тогда у вас есть только один параметр для проверки: яркость.
Ответ 6
Я понимаю, что этот разговор несколько лет, но он по-прежнему актуальен. Я хотел добавить, что моя команда имела ту же проблему в 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;
}
}
Ответ 7
Эта работа с hex, например #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;
}
Вы можете изменить его, чтобы вернуть true
или false
с помощью изменения
return (yiq < 40) ? '#2980b9' : hexcolor;
к
return (yiq < 40);