- commit
- 1126a01c61885de64eae7eb1152cd0e8c5e5958b
- parent
- 1cb50665affef87b2ef825e5aad0d2bfe6b749b6
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2022-07-16 19:59
normalize sRGBtoY before comparison
Diffstat
| M | analysis.md | 33 | +++++++++++++++++++++++++++------ |
| M | plots/sRGBtoY_comparison.png | 0 | |
| M | plots/sRGBtoY_comparison.py | 14 | ++++++++++++-- |
3 files changed, 39 insertions, 8 deletions
diff --git a/analysis.md b/analysis.md
@@ -185,7 +185,7 @@ function sRGBtoY_modified(srgb, exponent) {
185 185 if (y < 0.022) {
186 186 y += Math.pow(0.022 - y, 1.414);
187 187 }
188 -1 return Math.exp(Math.pow(y, exponent)) / Math.exp(1);
-1 188 return Math.exp(Math.pow(y, exponent));
189 189 }
190 190 ```
191 191
@@ -205,14 +205,35 @@ To get a better feeling for how these formulas compare, I plotted the results
205 205 of `sRGBtoY()`. In order to reduce colors to a single dimension, I used gray
206 206 `[x, x, x]`, red `[x, 0, 0]`, green `[0, x, 0]` and blue `[0, 0, x]` values.
207 207
-1 208 I also normalized the values so they are in the same range as WCAG 2.x. I used
-1 209 factors (because they do not change the contrast ratio) and powers (because
-1 210 they are monotonous on the contrast ratio).
-1 211
-1 212 ```js
-1 213 var average_exponent = 0.6;
-1 214 var y0 = Math.exp(Math.pow(0.022, 1.414 * average_exponent));
-1 215 var y1 = Math.exp(1);
-1 216
-1 217 function normalize(y) {
-1 218 // scale the lower end to 1
-1 219 y /= y0;
-1 220
-1 221 // scale the upper end to 21
-1 222 // we use a power so the lower end stays at 1
-1 223 y = Math.pow(y, Math.log(21) / Math.log(y1 / y0));
-1 224
-1 225 // scale down to the desired range
-1 226 return y / 20;
-1 227 }
-1 228 ```
-1 229
208 230 
209 231
210 232 The four curves for APCA are very similar. Despite the very different formula,
211 -1 the WCAG 2.x curve also has a similar shape, although it is a lot lower. I
212 -1 added another curve that uses the WCAG 2.x formula, but with an ambient light
213 -1 value of 0.6 instead of 0.05. This one is very similar to the APCA curves. The
214 -1 second column shows the differences between the APCA curves and this modified
215 -1 WCAG 2.x.
-1 233 the WCAG 2.x curve also has a similar shape. I added a modified WCAG 2.x curve
-1 234 with an ambient light value of 0.6 instead of 0.05. This one is very similar
-1 235 to the APCA curves. The second column shows the differences between the APCA
-1 236 curves and this modified WCAG 2.x.
216 237
217 238 The APCA contrast formula is certainly not as obvious a choice as the one from
218 239 WCAG 2.x. I was not able to find much information on how it was derived. A
diff --git a/plots/sRGBtoY_comparison.png b/plots/sRGBtoY_comparison.png
Binary files differ.diff --git a/plots/sRGBtoY_comparison.py b/plots/sRGBtoY_comparison.py
@@ -1,3 +1,5 @@ -1 1 import math -1 2 1 3 from matplotlib import pyplot as plt 2 4 import numpy as np 3 5 @@ -10,7 +12,11 @@ def wcag(x, factor, ambient): 10 12 y = x / 255 11 13 y = np.where(y < 0.04045, y / 12.92, ((y + 0.055) / 1.055) ** 2.4) 12 14 y *= factor13 -1 return (y + ambient) / (1 + ambient)-1 15 y += ambient -1 16 -1 17 y0 = ambient -1 18 y1 = 1 + ambient -1 19 return (y / y0) ** math.log(21, y1 / y0) / 20 14 20 15 21 16 22 def apca(x, factor, exp): @@ -19,7 +25,11 @@ def apca(x, factor, exp): 19 25 y *= factor 20 26 y += np.where(y < 0.022, 0.022 - y, 0) ** 1.414 21 27 y **= exp22 -1 return np.exp(y) / np.exp(1)-1 28 y = np.exp(y) -1 29 -1 30 y0 = math.exp((0.022 ** 1.414) ** 0.6) -1 31 y1 = math.exp(1) -1 32 return (y / y0) ** math.log(21, y1 / y0) / 20 23 33 24 34 25 35 if __name__ == '__main__':