Skip to content

Commit 4908aa7

Browse files
committed
Add example images of simulation of color deficiency
1 parent 2967ec5 commit 4908aa7

File tree

5 files changed

+124
-3
lines changed

5 files changed

+124
-3
lines changed

docs/crosssectionalcharts.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ function write_png(io::IO, cs::AbstractArray{T}) where T <: Color
172172
u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
173173
u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
174174
b(bstr) = write(buf, bstr)
175-
function pallet(c::Color)
175+
function palette(c::Color)
176176
rgb24 = convert(RGB24,c)
177177
u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
178178
end
@@ -197,7 +197,7 @@ function write_png(io::IO, cs::AbstractArray{T}) where T <: Color
197197
u32(n * n * 3); flush();
198198
b(b"PLTE")
199199
for y = 1:n, x = 1:n
200-
pallet(cs[y,x])
200+
palette(cs[y,x])
201201
end
202202
crc32()
203203
# Image data

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ include("crosssectionalcharts.jl")
1010
include("colordiffcharts.jl")
1111
include("colormaps.jl")
1212
include("namedcolorcharts.jl")
13+
include("sampleimages.jl")
1314

1415

1516
makedocs(

docs/sampleimages.jl

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
2+
module SampleImages
3+
4+
using Colors
5+
using Base64
6+
7+
struct BeadsImageSVG <: Main.SVG
8+
buf::IOBuffer
9+
end
10+
11+
12+
# The following code is ad-hoc and highly depends on "beads.svg".
13+
# Be careful when modifying the svg file or its code.
14+
function BeadsImageSVG(caption::String; filter=nothing, width="64mm", height="36mm")
15+
io = IOBuffer()
16+
id = string(hash(caption), base=16)
17+
18+
open(joinpath("assets", "figures", "beads.svg"), "r") do file
19+
for line in eachline(file, keep=true)
20+
occursin("<?xml", line) && continue
21+
if occursin("<svg", line)
22+
line = replace(line, ">"=>
23+
"""width="$width" height="$height" style="display:inline; margin-left:1em; margin-bottom:1em">""")
24+
elseif occursin("filter_beads_g", line)
25+
line = replace(line, "filter_beads_g"=>"filter_"*id)
26+
elseif occursin("</svg>", line)
27+
text = """
28+
<text x="16" y="1000" style="fill:black;opacity:0.9;font-size:80px;">$caption</text>
29+
</svg>"""
30+
line = replace(line, "</svg>"=>text)
31+
end
32+
33+
m = match(r"data:image/png;base64,([^\"]+)", line)
34+
if filter === nothing || m === nothing
35+
write(io, line)
36+
continue
37+
end
38+
39+
head = m.offsets[1]
40+
write(io, SubString(line, 1, head - 1))
41+
src = IOBuffer(m.captures[1])
42+
b64dec = Base64DecodePipe(src) # decode all for simplicity
43+
b64enc = Base64EncodePipe(io)
44+
write(b64enc, read(b64dec, 33)) # before the length of "PLTE"
45+
replace_palette(b64enc, b64dec, filter)
46+
n = write(b64enc, read(b64dec))
47+
close(b64enc)
48+
close(b64dec)
49+
write(io, SubString(line, head + length(m.captures[1]), length(line)))
50+
end
51+
end
52+
BeadsImageSVG(io)
53+
end
54+
55+
56+
function replace_palette(dest::IO, src::IO, filter)
57+
buf = IOBuffer() # to calculate chunk CRCs
58+
59+
u8(x) = write(buf, UInt8(x & 0xFF))
60+
u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
61+
u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
62+
function read_palette()
63+
uint32 = (UInt32(read(src, UInt8)) << 16) |
64+
(UInt32(read(src, UInt8)) << 8) | read(src, UInt8)
65+
reinterpret(RGB24, uint32)
66+
end
67+
function write_palette(c::Color)
68+
rgb24 = convert(RGB24,c)
69+
u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
70+
end
71+
crct(x) = (for i = 1:8; x = x & 1==1 ? 0xEDB88320 (x>>1) : x>>1 end; x)
72+
table = UInt32[crct(i) for i = 0x00:0xFF]
73+
function crc32()
74+
seekstart(buf)
75+
crc = 0xFFFFFFFF
76+
while !eof(buf)
77+
crc = (crc>>8) table[(crc&0xFF) read(buf, UInt8) + 1]
78+
end
79+
u32(crc 0xFFFFFFFF)
80+
end
81+
lenbytes = read(src, 4)
82+
len = (UInt32(lenbytes[3]) << 8) | lenbytes[4]
83+
write(dest, lenbytes)
84+
write(buf, read(src, 4)) # "PLTE"
85+
for i = 1:(len÷3)
86+
write_palette(filter(read_palette()))
87+
end
88+
read(src, 4) # CRC
89+
crc32()
90+
write(dest, take!(seekstart(buf)))
91+
end
92+
93+
end

docs/src/advancedfunctions.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,22 @@ deuteranopic(c::Color, p::Float64)
4848
tritanopic(c::Color, p::Float64)
4949
```
5050

51-
Also provided are versions of these functions with an extra parameter `p` in `[0, 1]`, giving the degree of photopigment loss, where 1.0 is a complete loss, and 0.0 is no loss at all.
51+
Also provided are versions of these functions with an extra parameter `p` in `[0, 1]`, giving the degree of photopigment loss, where `1.0` is a complete loss, and `0.0` is no loss at all. The partial loss simulates the anomalous trichromacy, i.e. *protanomaly*, *deuteranomaly* and *tritanomaly*.
52+
53+
```@example deficiency
54+
using Colors #hide
55+
using Main: SampleImages # hide
56+
SampleImages.BeadsImageSVG("Normal") # hide
57+
```
58+
```@example deficiency
59+
SampleImages.BeadsImageSVG("Protanomaly (p=0.7)", filter=(c->protanopic(c, 0.7))) # hide
60+
```
61+
```@example deficiency
62+
SampleImages.BeadsImageSVG("Deuteranomaly (p=0.7)", filter=(c->deuteranopic(c, 0.7))) # hide
63+
```
64+
```@example deficiency
65+
SampleImages.BeadsImageSVG("Tritanomaly (p=0.7)", filter=(c->tritanopic(c, 0.7))) # hide
66+
```
5267

5368
```@docs
5469
protanopic

0 commit comments

Comments
 (0)