Colour-vision simulation: how a colour reads to a person with one of the three dichromacies (spec/08 §1.8, D-139).
The model is Machado, Oliveira and Fernandes (2009), "A Physiologically-based Model for
Simulation of Color Vision Deficiency", IEEE Transactions on Visualization and Computer
Graphics 15(6), 1291–1298, at severity 1.0. A colour is decoded from sRGB to linear RGB,
multiplied by the deficiency's matrix, clamped to 0..1 and encoded back; its opacity is
kept. Each matrix's rows sum to 1, so a grey is its own simulation.
It is a transform for judging a palette by eye — the theme editor draws its ramps and its preview through it — and nothing in the library draws through it on its own.
Examples
iex> red = Visualize.Color.parse("#ff0000")
iex> Visualize.Color.Vision.simulate(red, :protanopia) |> Visualize.Color.to_hex()
"#6d5f00"
iex> grey = Visualize.Color.parse("#808080")
iex> Visualize.Color.Vision.simulate(grey, :tritanopia) |> Visualize.Color.to_hex()
"#808080"
Summary
Types
A dichromacy the model simulates, or :none for the colour as it is.
Functions
The deficiencies the model simulates: [:protanopia, :deuteranopia, :tritanopia].
The deficiency's matrix over linear RGB, as three rows (Machado et al. 2009, severity 1.0).
The text with every #rrggbb and #rgb colour literal replaced by its simulation, as
#rrggbb — an SVG's fills and strokes, a style's colours. A # that is a reference,
url(#id), is left alone, and so is everything that is not a colour; :none is the text.
The colour as the deficiency sees it, its opacity kept; :none is the colour itself.
Any other atom raises ArgumentError.
Types
Functions
@spec deficiencies() :: [deficiency(), ...]
The deficiencies the model simulates: [:protanopia, :deuteranopia, :tritanopia].
@spec matrix(deficiency()) :: [[float()]]
The deficiency's matrix over linear RGB, as three rows (Machado et al. 2009, severity 1.0).
iex> Visualize.Color.Vision.matrix(:deuteranopia) |> hd()
[0.367322, 0.860646, -0.227968]
@spec recolour(String.t(), deficiency() | :none) :: String.t()
The text with every #rrggbb and #rgb colour literal replaced by its simulation, as
#rrggbb — an SVG's fills and strokes, a style's colours. A # that is a reference,
url(#id), is left alone, and so is everything that is not a colour; :none is the text.
iex> Visualize.Color.Vision.recolour(~s|<rect fill="#ff0000" mask="url(#bad)"/>|, :protanopia)
~s|<rect fill="#6d5f00" mask="url(#bad)"/>|
@spec simulate(Visualize.Color.t(), deficiency() | :none) :: Visualize.Color.t()
The colour as the deficiency sees it, its opacity kept; :none is the colour itself.
Any other atom raises ArgumentError.