apca-introduction

The missing introduction to APCA  https://p.ce9e.org/apca-introduction/
git clone https://git.ce9e.org/apca-introduction.git

commit
00ef8b24583a2279873d3c0aecc882046187b8a6
parent
8596c1c989f1b973de6dcd67f68803419997cce1
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-07-17 14:27
add contrast comparison

Diffstat

A plots/contrast_comparison.png 0
A plots/contrast_comparison.py 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2 files changed, 82 insertions, 0 deletions


diff --git a/plots/contrast_comparison.png b/plots/contrast_comparison.png

Binary files differ.

diff --git a/plots/contrast_comparison.py b/plots/contrast_comparison.py

@@ -0,0 +1,82 @@
   -1     1 import math
   -1     2 
   -1     3 from matplotlib import pyplot as plt
   -1     4 import numpy as np
   -1     5 
   -1     6 
   -1     7 def wcag_y(color):
   -1     8 	c = color / 255
   -1     9 	c = np.where(c < 0.04045, c / 12.92, ((c + 0.055) / 1.055) ** 2.4)
   -1    10 	return 0.2126 * c[:, 0] + 0.7152 * c[:, 1] + 0.0722 * c[:, 2]
   -1    11 
   -1    12 
   -1    13 def wcag_contrast(yfg, ybg, ambient=0.05):
   -1    14 	c = (ybg + ambient) / (yfg + ambient)
   -1    15 
   -1    16 	y0 = ambient
   -1    17 	y1 = 1 + ambient
   -1    18 	return c ** math.log(21, y1 / y0)
   -1    19 
   -1    20 
   -1    21 def apca_y(color):
   -1    22 	c = color / 255
   -1    23 	c **= 2.4
   -1    24 	y = 0.2126729 * c[:, 0] + 0.7151522 * c[:, 1] + 0.0721750 * c[:, 2]
   -1    25 	y += np.where(y < 0.022, 0.022 - y, 0) ** 1.414
   -1    26 	return y
   -1    27 
   -1    28 
   -1    29 def apca_contrast(yfg, ybg):
   -1    30 	_yfg = yfg ** np.where(ybg > yfg, 0.57, 0.62)
   -1    31 	_ybg = ybg ** np.where(ybg > yfg, 0.56, 0.65)
   -1    32 	c = _ybg - _yfg
   -1    33 	c = np.exp(c)
   -1    34 
   -1    35 	y0 = math.exp((0.022 ** 1.414) ** 0.6)
   -1    36 	y1 = math.exp(1)
   -1    37 	return c ** math.log(21, y1 / y0)
   -1    38 
   -1    39 
   -1    40 if __name__ == '__main__':
   -1    41 	fig, axes = plt.subplots(2, 2, sharex='row', sharey='row', figsize=(6, 6))
   -1    42 
   -1    43 	options = {
   -1    44 		'marker': '.',
   -1    45 		'cmap': 'seismic',
   -1    46 	}
   -1    47 
   -1    48 	size = 10_000
   -1    49 	fg = np.random.randint(0, 256, size=(size, 3))
   -1    50 	bg = np.random.randint(0, 256, size=(size, 3))
   -1    51 
   -1    52 	apca_yfg = apca_y(fg)
   -1    53 	apca_ybg = apca_y(bg)
   -1    54 	apca = apca_contrast(apca_yfg, apca_ybg)
   -1    55 
   -1    56 	wcag_yfg = wcag_y(fg)
   -1    57 	wcag_ybg = wcag_y(bg)
   -1    58 	wcag = wcag_contrast(wcag_yfg, wcag_ybg)
   -1    59 	wcag4 = wcag_contrast(wcag_yfg, wcag_ybg, 0.4)
   -1    60 
   -1    61 	axes[0][0].set_title('APCA vs WCAG 2.x')
   -1    62 
   -1    63 	axes[0][0].scatter(wcag, apca, **options)
   -1    64 	axes[0][0].set_xlabel('WCAG 2.x')
   -1    65 	axes[0][0].set_ylabel('APCA')
   -1    66 
   -1    67 	axes[1][0].scatter(wcag_yfg, wcag_ybg, c=np.log(apca / wcag), **options)
   -1    68 	axes[1][0].set_xlabel('Yfg')
   -1    69 	axes[1][0].set_ylabel('Ybg')
   -1    70 
   -1    71 	axes[0][1].set_title('APCA vs WCAG 2.x (0.4)')
   -1    72 
   -1    73 	axes[0][1].scatter(wcag4, apca, **options)
   -1    74 	axes[0][1].set_xlabel('WCAG 2.x (0.4)')
   -1    75 	axes[0][1].set_ylabel('APCA')
   -1    76 
   -1    77 	axes[1][1].scatter(wcag_yfg, wcag_ybg, c=np.log(apca / wcag4), **options)
   -1    78 	axes[1][1].set_xlabel('Yfg')
   -1    79 	axes[1][1].set_ylabel('Ybg')
   -1    80 
   -1    81 	plt.tight_layout()
   -1    82 	plt.savefig('contrast_comparison.png')