From 1aacb5535826c8a4eb43256cd4274731eb57a841 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 10 Sep 2022 08:45:29 +0200 Subject: [PATCH 1/4] typo --- docs/contrast.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contrast.md b/docs/contrast.md index 4c392a240..c371fb401 100644 --- a/docs/contrast.md +++ b/docs/contrast.md @@ -209,7 +209,7 @@ _This value is much higher than that in the sRGB standard, which puts white at 80 cd/m2 and black at 0.2cd/m2, a relative luminance boost of 0.0025._ -> WCAG21 = = (Ymax + 0.05) / (Ymin + 0.05) +> WCAG21 = (Ymax + 0.05) / (Ymin + 0.05) Because of it's widespread use, color.js provides this method, mainly to aid comparison. From 1f7e930467cbcf922a4a5e552b25cae293a159f5 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 10 Sep 2022 09:26:36 +0200 Subject: [PATCH 2/4] Fix parens in Weber contrast docs --- docs/contrast.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/contrast.md b/docs/contrast.md index c371fb401..5b96ed923 100644 --- a/docs/contrast.md +++ b/docs/contrast.md @@ -67,7 +67,7 @@ It is commonly used in lighting design, and also to examine small, sharp edged symbols and text on larger, uniformly-colored backgrounds. -> WC = Ymax - Ymin / Ymin +> WC = (Ymax - Ymin) / Ymin Any two colors can be used, and this formula does not care which is the text color and which is the background. @@ -85,7 +85,7 @@ Weber contrast is typically used with printed test charts with positive polarity (black text, white background). The formula thus can be expressed as: -> WCpp = Ybackground - Ytext / Ytext +> WCpp = (Ybackground - Ytext) / Ytext Hwang and Peli used a modified Weber contrast for tablet-based, negative polarity testing (white text on black background), @@ -95,7 +95,7 @@ and wrote: The formula for negative polarity is -> WCnp = Ytext - Ybackground / Ytext +> WCnp = (Ytext - Ybackground) / Ytext ## Michelson Contrast From 79a96be2fb2820fa2685c78b653b4b65b4b74d00 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 10 Sep 2022 09:08:40 +0200 Subject: [PATCH 3/4] Allow to pass offset to Weber contrast --- docs/contrast.md | 14 ++++++++++++++ src/contrast/Weber.js | 8 ++++---- tests/contrast.html | 22 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/docs/contrast.md b/docs/contrast.md index 5b96ed923..8ce6f17cc 100644 --- a/docs/contrast.md +++ b/docs/contrast.md @@ -97,6 +97,18 @@ The formula for negative polarity is > WCnp = (Ytext - Ybackground) / Ytext +In another paper, Hwang and Peli proposed to add +a fixed luminance to both colors to account for viewing flare: + +> WC = (Ymax - Ymin) / (Ymin + Yambient) + +The value of that offset depends on the viewing conditions. + +```js +let color1 = new Color("p3", [0.9, 0.8, 0.1]); +let color2 = new Color("slategrey"); +let contrast = color1.contrast(color2, {algorithm: "weber", offset: .05}); +``` ## Michelson Contrast @@ -235,6 +247,8 @@ let contrast = color1.contrast(color2, "WCAG21"); - Alex D. Hwang and Eli Peli (2016) _Positive and negative polarity contrast sensitivity measuring app_. IS&T Int Symp Electron Imaging 2016: 10.2352. [full article](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5481843/) +- Alex D. Hwang and Eli Peli (2016) _New Contrast Metric for Realistic Display Performance Measure._. Dig Tech Pap. 2016: 10.1002. [full article](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5489230/) + - Gordon E. Legge, David H. Parish, Andrew Luebker, and Lee H. Wurm (1990) _Psychophysics of reading. XI. Comparing color contrast and luminance contrast_. Journal of the Optical Society of America vol **7** issue 10 pp. 2002-2010 [https://doi.org/10.1364/JOSAA.7.002002](https://doi.org/10.1364/JOSAA.7.002002) - Gordon E.Legge, Gary S.Rubin, Andrew Luebker (1987) _Psychophysics of reading—V. The role of contrast in normal vision_. Vision Research vol **27**, Issue 7, pp. 1165-1177 [abstract](https://www.sciencedirect.com/science/article/abs/pii/0042698987900289) diff --git a/src/contrast/Weber.js b/src/contrast/Weber.js index c70cdf50d..f2fd240e9 100644 --- a/src/contrast/Weber.js +++ b/src/contrast/Weber.js @@ -1,7 +1,7 @@ // Weber luminance contrast // The difference between the two luminances divided by the lower luminance // Symmetric, does not matter which is foreground and which is background -// No black level compensation for flare. +// Optional offset for flare contribution import getColor from "../getColor.js"; import {getLuminance} from "../luminance.js"; @@ -12,12 +12,12 @@ import {getLuminance} from "../luminance.js"; // max clamp for the plain Weber const max = 50000; -export default function contrastWeber (color1, color2) { +export default function contrastWeber (color1, color2, {offset = 0} = {}) { color1 = getColor(color1); color2 = getColor(color2); - let Y1 = Math.max(getLuminance(color1), 0); - let Y2 = Math.max(getLuminance(color2), 0); + let Y1 = Math.max(getLuminance(color1), 0) + offset; + let Y2 = Math.max(getLuminance(color2), 0) + offset; if (Y2 > Y1) { [Y1, Y2] = [Y2, Y1]; diff --git a/tests/contrast.html b/tests/contrast.html index 04e0c5885..5b19c49d3 100644 --- a/tests/contrast.html +++ b/tests/contrast.html @@ -461,6 +461,28 @@

Weber contrast, sRGB

+
+

Weber contrast with offset

+ + + + + + + + + + + + + +
whitewhite + + 0
whiteblack + + 20
+
+

Michelson contrast, sRGB

Same test color pairs as apca-w3 test.

From 49fab6ff51eefa51f901bb55a9c31a41d6700de1 Mon Sep 17 00:00:00 2001 From: Tobias Bengfort Date: Sat, 10 Sep 2022 09:09:08 +0200 Subject: [PATCH 4/4] Add parametrized Stevens contrast --- docs/contrast.md | 16 ++++++++ src/contrast/Stevens.js | 19 +++++++++ src/contrast/index.js | 1 + tests/contrast.html | 86 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 src/contrast/Stevens.js diff --git a/docs/contrast.md b/docs/contrast.md index 8ce6f17cc..318da8dbf 100644 --- a/docs/contrast.md +++ b/docs/contrast.md @@ -135,6 +135,22 @@ let color2 = new Color("slategrey"); let contrast = color1.contrast(color2, "Michelson"); ``` +## Stevens Contrast + +Stevens contrast is often considered to supersede the Weber contrast. +It is based on powers rather than logarithms. + +> SC = Ymaxexp - Yminexp + +The value of that exponent depends on the viewing conditions. +It is also possible to use an offset to model flare. + +```js +let color1 = new Color("p3", [0.9, 0.8, 0.1]); +let color2 = new Color("slategrey"); +let contrast = color1.contrast(color2, {algorithm: "stevens", exponent: 1 / 3, offset: .0025}); +``` + ## Accessible Perceptual Contrast Algorithm (APCA) APCA is part of a color appearance system to determine _readability contrast_ diff --git a/src/contrast/Stevens.js b/src/contrast/Stevens.js new file mode 100644 index 000000000..70987a198 --- /dev/null +++ b/src/contrast/Stevens.js @@ -0,0 +1,19 @@ +// Stevens contrast +// Symmetric, does not matter which is foreground and which is background +// Viewing conditions can be modified by changing exponent and offset + +import getColor from "../getColor.js"; +import {getLuminance} from "../luminance.js"; + +export default function contrastStevens (color1, color2, {exponent = 1 / 3, offset = .0025} = {}) { + color1 = getColor(color1); + color2 = getColor(color2); + + let Y1 = Math.max(getLuminance(color1), 0) + offset; + let Y2 = Math.max(getLuminance(color2), 0) + offset; + + let J1 = Math.pow(Y1, exponent); + let J2 = Math.pow(Y2, exponent); + + return Math.abs(J1 - J2); +}; diff --git a/src/contrast/index.js b/src/contrast/index.js index 5a54c25a8..b30e7e40a 100644 --- a/src/contrast/index.js +++ b/src/contrast/index.js @@ -2,5 +2,6 @@ export {default as contrastWCAG21} from "./WCAG21.js"; export {default as contrastAPCA} from "./APCA.js"; export {default as contrastMichelson} from "./Michelson.js"; export {default as contrastWeber} from "./Weber.js"; +export {default as contrastStevens} from "./Stevens.js"; export {default as contrastLstar} from "./Lstar.js"; export {default as contrastDeltaPhi} from "./deltaPhi.js"; diff --git a/tests/contrast.html b/tests/contrast.html index 5b19c49d3..b02c5027a 100644 --- a/tests/contrast.html +++ b/tests/contrast.html @@ -555,6 +555,92 @@

Michelson contrast, sRGB

+
+

Stevens contrast, sRGB

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
whiteblack + + 0.8651117590220451
whitewhite + + 0
#888#fff + + 0.37196482640638906
#fff#888 + + 0.37196482640638906
#000#aaa + + 0.6038246032876674
#aaa#000 + + 0.6038246032876674
#123#def + + 0.6837707144018808
#def#123 + + 0.6837707144018808
#123#444 + + 0.13241705354214078
#444#123 + + 0.13241705354214078
+
+