Таким образом, учитывая # 000000 и # 444444, вы можете рассчитать коэффициент контрастности (в данном случае 2,15). Математика довольно проста, хотя и немного волосатая. (См. Определение « относительная яркость ».)
Теперь вы хотите вернуться назад? Если у вас # 000000 и вы хотите соотношение 4,5, начиная с # 444444, каким должен быть цвет? Это то, что
Мне нужно изменить формулу контрастности
означает
Это немного сложно, потому что вы решаете для 3 переменных, красного, зеленого и синего компонентов, плюс формула яркости не одинаково обрабатывает красный, зеленый и синий. Он использует 21,25% красного, 71,5% зеленого и 7,25% синего.
Кроме того, формула яркости не является простой линейной формулой, поэтому вы не можете просто взять процент, не соответствующий яркости, и увеличить значение цвета на тот же процент.
Например, в вашем случае соотношение было 2,15, но вам нужно, чтобы оно было 4,5. 2,15 составляет 108% от 4,5, желаемое значение.
Однако, если вы посмотрите на свои исходные значения RGB # 444444 и вычислили, что они должны быть равны # 757575 (для того, чтобы иметь отношение 4,5), то если вы рассматриваете эти значения RGB как простые числа (и преобразуете в десятичное число) тогда # 444444 (4473924) на 72% меньше, чем # 757575 (7697781).
Таким образом, у вас есть разрыв, что ваше соотношение короткое на 108%, а ваши значения RGB короткие на 72%. Таким образом, вы не можете сделать простое линейное уравнение.
( Числа не совсем точны, так как # 757575 дает вам соотношение 4,56, а не точное 4,5. Если вы используете # 747474, вы получите соотношение 4,49, что для WCAG слишком мало. соответствие, но ближе к 4,5, чем к 4,56. Однако # 444444 отстает на 71% от # 747474, так что это не то же самое, что 2,15 с 108% от 4,5, поэтому базовая концепция все еще применима. )
Ради интереса я посмотрел значения от 0x11111 до 0x666666, увеличив их на 0x111111, и рассчитал коэффициент контрастности. На графике было недостаточно точек, поэтому я добавил цвет на полпути между 0x111111 и 0x222222, затем на полпути между 0x222222 и 0x333333 и т. Д.
RGB contrast % from 4.5 % from 0x747474
111111 1.11 305.41% 582.35%
191919 1.19 278.15% 364.00%
222222 1.32 240.91% 241.18%
2a2a2a 1.46 208.22% 176.19%
333333 1.66 171.08% 127.45%
3b3b3b 1.87 140.64% 96.61%
444444 2.16 108.33% 70.59%
4c4c4c 2.45 83.67% 52.63%
555555 2.82 59.57% 36.47%
5d5d5d 3.19 41.07% 24.73%
666666 3.66 22.95% 13.73%
6e6e6e 4.12 9.22% 5.45%
Как видите, линии пересекаются в третьей точке данных, а затем сходятся друг к другу. Я уверен, что здесь есть формула, чтобы вы могли взять процент контрастности, выполнить некоторую (возможно, логарифмическую) функцию и получить процент, необходимый для изменения цвета.
Это была бы увлекательная математическая задача, с которой у меня сейчас нет времени играть.
Обновление 18 января 2019
Я заставил его работать в обратном направлении, но он не обрабатывает крайние случаи, например, когда темный цвет становится темнее, но вы уже достигли максимума (или более светлого цвета, но вы достигли максимума). Но, может быть, вы можете играть с ним.
Контрольный пример
#ee0add
для светлого цвета (пурпурный)
#445566
для темного цвета (темно-серый)
- коэффициент контрастности 2,09
При вычислении " относительной яркости " цвета он имеет условное выражение.
if X <= 0.03928 then
X = X/12.92
else
X = ((X+0.055)/1.055) ^ 2.4
До того, как X будет использоваться в этом условии, он делится на 255, чтобы нормализовать значение между 0 и 1. Так что, если вы возьмете условное значение, 0,03928 и , умножьте на 255 , вы получите 10.0164. Так как значения RGB должны быть целыми числами, это означает, что компонент RGB 10 (0x0A) или меньше будет проходить через «if», а все 11 (0x0B) или больше будут проходить через «else». Поэтому в моих тестовых значениях я хотел, чтобы одна из цветовых частей была 10 (0x0A) (# EE 0A DD).
Относительная яркость для # ee0add составляет 0,23614683378171950172526363525113 (0,236)
Относительная яркость для # 445566 составляет 0,0868525191131797135799815832377 (0,0868)
Коэффициент контрастности
(0,236 + 0,05) / (0,0868 + 0,05) = 2,09
(Вы можете проверить это соотношение на https://webaim.org/resources/contrastchecker/?fcolor=EE0ADD&bcolor=445566)
Если мы хотим, чтобы отношение равнялось 4,5, и мы хотим, чтобы # ee0add не менялось, мы должны отрегулировать # 445566. Это означает, что вам нужно решить для:
4.5 = (0.236 + .05) / (XX + .05)
Таким образом, второе значение яркости (XX) должно быть 0,01358818528482655593894747450025 (0,0136)
Исходное второе значение яркости было 0,0868525191131797135799815832377 (0,0868), поэтому для получения 0,01358818528482655593894747450025 (0,0136) нам нужно умножить исходное значение на 0,15645125119651910313960717062698 (0,0136 / 0,86%) = 0,60 * 0,60% = 0,60 * 0,60 = 0,66 * 0,668 = =
Если мы применим эти 15,6% к каждому из значений относительной яркости R, G и B, а затем проработаем условное выражение, приведенное выше, вы можете получить значения RGB.
Исходная яркость для # 445566
r = 0x44 = 68
g = 0x55 = 85
b = 0x66 = 102
r1 = 68 / 255 = 0.26666666666666666666666666666667
g1 = 85 / 255 = 0.33333333333333333333333333333333
b1 = 102 / 255 = 0.4
r2 = ((.267 + .055) / 1.055)^^2.4 = 0.05780543019106721120703816752337
g2 = ((.333 + .055) / 1.055)^^2.4 = 0.09084171118340767766490119106965
b2 = ((.400 + .055) / 1.055)^^2.4 = 0.13286832155381791428570549818868
l = 0.2126 * r2 + 0.7152 * g2 + 0.0722 * b2
= 0.0868525191131797135799815832377
Работая в обратном направлении, взять 15,6% от значений r2, g2 и b2
r2 = 0.05780543019106721120703816752337 * 15.6% = 0.00904373187934550551617004082875
g2 = 0.09084171118340767766490119106965 * 15.6% = 0.01421229937547695322310904970549
b2 = 0.13286832155381791428570549818868 * 15.6% = 0.02078741515147623990363062978804
Теперь отмените этот беспорядок с ^^2.4
и другими вещами
- чтобы отменить
X^^2.4
вы должны сделать обратное, X^^(1/2.4)
или X^^(0.4167)
- затем умножить на 1,055
- затем вычесть 0,055
- затем умножить на 255
pow( 0.00904373187934550551617004082875, 1/2.4) = 0.14075965680504652191078668676178
pow( 0.01421229937547695322310904970549, 1/2.4) = 0.16993264267137740728089791717873
pow( 0.02078741515147623990363062978804, 1/2.4) = 0.19910562853770829265100914759565
умножить на 1,055
0.14075965680504652191078668676178 * 1.055 = 0.14850143792932408061587995453368
0.16993264267137740728089791717873 * 1.055 = 0.17927893801830316468134730262356
0.19910562853770829265100914759565 * 1.055 = 0.21005643810728224874681465071341
вычесть 0,055
0.14850143792932408061587995453368 - 0.055 = 0.09350143792932408061587995453368
0.17927893801830316468134730262356 - 0.055 = 0.12427893801830316468134730262356
0.21005643810728224874681465071341 - 0.055 = 0.15505643810728224874681465071341
умножить на 255
0.09350143792932408061587995453368 * 255 = 23.842866671977640557049388406088 = 24 = 0x18
0.12427893801830316468134730262356 * 255 = 31.691129194667306993743562169008 = 32 = 0x20
0.15505643810728224874681465071341 * 255 = 39.53939171735697343043773593192 = 40 = 0x28
Итак, темный цвет - # 182028. Возможно, есть некоторые ошибки округления, но если вы проверите исходный цвет переднего плана, # ee0add с новым цветом, # 182028, вы получите коэффициент контрастности 4,48. Просто стесняюсь 4,5, но, как я уже сказал, возможно, некоторые ошибки округления.
https://webaim.org/resources/contrastchecker/?fcolor=EE0ADD&bcolor=182028
Я пытался сделать то же самое с # ee0add, сохранив то же самое # 445566, но при переходе назад и переходе к последнему шагу, где вы умножаете на 255, я получил числа больше 255, которые не являются действительными компонентами RGB (они может идти только до 0xFF). Если я остановил число на 255, затем взял разницу и добавил ее к наименьшему значению цвета, я получил приличный цвет, но соотношение было 5,04, превышение 4,5. Я тоже могу опубликовать эту математику.