ОТВЕТ НА СЛЕДУЮЩИЙ
Я публикую это в качестве дополнительного ответа, чтобы не только уточнить мой первоначальный ответ (который я также только что отредактировал), но также добавить фрагменты кода различных концепций.Каждый шаг в процессе от R´G´B´ до Y важен, а также должен быть в порядке, описанном , иначе результаты не получатся.
ОПРЕДЕЛЕНИЯ:
sRGB : sRGB - это трехцветная цветовая модель, которая является стандартом для Интернета и используется на большинстве компьютерных мониторов.Он использует те же основные цвета и белую точку, что и Rec709, стандарт для HDTV.sRGB отличается от Rec709 только кривой передачи, часто называемой гаммой.
Гамма: Эта кривая используется с различными методами кодирования изображений для хранения и передачи.Это часто похоже на кривую восприятия человеческого зрения.В цифровом гамма-эффект заключается в придании большего веса темным областям изображения, чтобы они определялись большим количеством битов, чтобы избежать таких артефактов, как «полосатость».
Яркость: (примечание L или Y ): линейная мера или представление света (т.е. НЕТ гамма-кривой).В качестве меры обычно используется кд / м 2 .В качестве представления это Y, как в CIEXYZ, и обычно от 0 (черный) до 100 (белый) .Яркость характеризуется спектральным взвешиванием, основанным на восприятии человеком различных длин волн света.Тем не менее, яркость является линейной с точки зрения яркости / темноты - то есть, если 100 фотонов света измеряют 10, то 20 будет 200 фотонов света.
L * (он же Lstar):Легкость восприятия, как определено в CIELAB (L * a * b *). Если яркость является линейной с точки зрения количества света, L * основана на восприятии и поэтому является нелинейной с точки зрения количества света, с кривой, предназначенной для соответствияфотопическое зрение человеческого глаза (приблиз. гамма ^ 0,43).
Яркость по сравнению с L *: 0 и 100 равны одинаковы в обеих яркостях (записано Y илиL) и Легкость (написано L *), но в середине они очень разные.То, что мы называем средним серым, находится в самой середине L * на 50, но это относится к 18,4 в яркости (Y).В sRGB это # 777777 или 46,7%.
Контраст: Термин для определения разницы между двумя значениями L или Y.Есть несколько методов и стандартов для контраста.Одним из распространенных методов является контраст Вебера, который равен ΔL / L.Контрастность обычно указывается в виде соотношения (3: 1) или в процентах (70%).
ПОЛУЧЕНИЕ СВЕТА (Y) ОТ sRGB
STEP ZERO (un-HEX)
При необходимости преобразуйте значение цвета HEX в триплет целочисленных значений, где #00 = 0
и #FF = 255
.
STEP ONE (8-битный в десятичный)
Преобразование 8-битных значений sRGBв десятичное число путем деления на 255:
R´ десятичное = R´ 8bit / 255 G´ десятичное = G´ 8bit / 255 B´ десятичное число = B´ 8bit / 255
Если ваши значения sRGB 16-разрядные, то преобразуйте в десятичное числоделение на 65535.
ШАГ ВТОРОЙ (Linearize, Simple Version)
Повышение каждого цветового канала до уровня 2,2, аналогично дисплею sRGB.Это хорошо для большинства приложений.Но если вам нужно совершить многократные поездки в пространство гамма-кодирования sRGB, используйте более точные версии ниже.
R´ ^ 2.2 = R lin G´^ 2.2 = G lin B´ ^ 2.2 = B lin
STEP TWO (линеаризация, точная версия)
Используйте эту версиювместо простой версии 2.2, описанной выше, если вы выполняете манипуляции с изображениями и многократные циклические переходы в и из гамма-кодированного пространства.
function sRGBtoLin(colorChannel) {
// Send this function a decimal sRGB gamma encoded color value
// between 0.0 and 1.0, and it returns a linearized value.
if ( colorChannel <= 0.04045 ) {
return colorChannel / 12.92;
} else {
return Math.pow((( colorChannel + 0.055)/1.055),2.4));
}
}
ШАГ ТРИ (Спектрально-взвешенная яркость)
НорУ человеческого глаза есть три типа колбочек, чувствительных к красному, зеленому и синему свету.Но наша спектральная чувствительность не одинакова, так как мы наиболее чувствительны к зеленому (555 нм), а синий - последнее отдаленное место.Яркость спектрально взвешена, чтобы отразить это, используя следующие коэффициенты:
R lin * 0.2126 + G lin * 0.7152 + B lin * 0.0722 = Y = L
Умножьте каждый линеаризованный цветной канал на их коэффициент и сложите их все вместе, чтобы найти L, Яркость.
ШАГ ЧЕТЫРЕ (Определение контрастности)
Существует множество различных способов определения контраста, а также различные стандарты.Некоторые уравнения работают лучше, чем другие, в зависимости от конкретного применения.
WCAG
Текущий стандарт веб-страниц, указанный в WCAG 2.0 и 2.1, отличается от простого:
C = ((L светлее + 0,05) / (L темнее + 0,05)): 1
Это дает соотношение, истандарты WCAG определяют 3: 1 для нетекстовых и 4,5: 1 для текстовых.
Однако это слабый пример по ряду причин.Я официально отмечаю недостатки в текущем выпуске GitHub (695) и изучаю альтернативы.
Модифицированный Вебер
Модифицированный Вебер Hwang / Peli Модифицированный Вебер обеспечивает лучшую оценку контрастности применительно к компьютерным мониторам / sRGB.
C = (L светлее - L темнее ) / (L светлее + 0,1)
Обратите внимание, что я выбрал коэффициент вспышки 0,1 вместо 0,05, основываясь на некоторых недавних экспериментах.Это значение равно TBD, и другое значение может быть лучше.
Разница LAB
Другая альтернатива, которая мне нравится больше, чем другие, - преобразование линеаризованной яркости (L ) в L *, что означает Легкость восприятия, затем просто вычитая одно из другого, чтобы найти разницу.
Преобразование Y в L *:
function YtoLstar(Y) {
// Send this function a luminance value between 0.0 and 1.0,
// and it returns L* - perceptual lightness
if ( Y <= (216/24389) { // The CIE standard states 0.008856 but 216/24389 is the intent for 0.008856451679036
return Y * (24389/27); // The CIE standard states 903.3, but 24389/27 is the intent, making 903.296296296296296
} else {
return Math.pow(Y,(1/3)) * 116 - 16;
}
}
После того, как вы преобразовали L в L *, полезная контрастная фигура выглядит просто:
C = L * светлее - L * темнее
Возможно, здесь результаты должны быть масштабированы, чтобы быть похожими на другие методы.Масштабирование около 1,6 или 1,7, похоже, хорошо работает.
Существует ряд других методов определения контрастности, но они являются наиболее распространенными.Некоторые приложения, тем не менее, будут лучше с другими методами контраста.Некоторые другие - это контраст Майклсона, длина контрастности восприятия (PCL) и Боуман / Саполински.
ТАКЖЕ, если вы ищете цветовых различий за пределами различий в яркости или яркости, то CIELAB имеет некоторыеполезные методы в этом отношении.
ПОБОЧНЫЕ ПРИМЕЧАНИЯ:
Усреднение RGB Нет Bueno!
OP 2x2p упомянул широко цитируемое уравнение для создания оттенков серого цвета в виде:
СЕРЫЙ = круглый ((R + G + B) / 3);
Он указал, насколько неточно это выглядело, и действительно - это совершенно неправильно .Спектральные веса R, G и B являются существенными и не могут быть пропущены.ЗЕЛЕНЫЙ - это более высокая яркость, чем СИНИЙ на ПОРЯДОК МАГНИТНОСТИ. Вы не можете просто суммировать все три канала вместе, разделить на три и получить что-нибудь близкое к фактической яркости определенного цвета.
Я полагаю, что путаница по этому поводу могла возникнуть из-за управления цветом, известного как HSI (оттенок, насыщенность, интенсивность) .Но этот контроль не является (и никогда не должен быть) перцепционно однородным !!!HSI, как и HSV, - это просто «удобство» для манипулирования значениями цвета в компьютере.Они не одинаковы по восприятию, и математика, которую они используют, предназначена исключительно для поддержки «простого» способа настройки значений цвета в программном обеспечении.
Образцы цветов OP
2x2p опубликовал свой код, используя '# 318261', '# 9d5fb0' в качестве тестовых цветов.Вот как они выглядят в моей электронной таблице вместе с каждым значением на каждом этапе процесса преобразования (используя «точный» метод sRGB):
Оба близки к среднему серому # 777777.Обратите также внимание на то, что в то время как яркость L составляет всего 18, воспринимаемая яркость L * составляет 50.