Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example images of simulation of color deficiency #413

Merged
merged 1 commit into from
Mar 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/crosssectionalcharts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ function write_png(io::IO, cs::AbstractArray{T}) where T <: Color
u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
b(bstr) = write(buf, bstr)
function pallet(c::Color)
function palette(c::Color)
rgb24 = convert(RGB24,c)
u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
end
Expand All @@ -197,7 +197,7 @@ function write_png(io::IO, cs::AbstractArray{T}) where T <: Color
u32(n * n * 3); flush();
b(b"PLTE")
for y = 1:n, x = 1:n
pallet(cs[y,x])
palette(cs[y,x])
end
crc32()
# Image data
Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ include("crosssectionalcharts.jl")
include("colordiffcharts.jl")
include("colormaps.jl")
include("namedcolorcharts.jl")
include("sampleimages.jl")


makedocs(
Expand Down
93 changes: 93 additions & 0 deletions docs/sampleimages.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

module SampleImages

using Colors
using Base64

struct BeadsImageSVG <: Main.SVG
buf::IOBuffer
end


# The following code is ad-hoc and highly depends on "beads.svg".
# Be careful when modifying the svg file or its code.
function BeadsImageSVG(caption::String; filter=nothing, width="64mm", height="36mm")
io = IOBuffer()
id = string(hash(caption), base=16)

open(joinpath("assets", "figures", "beads.svg"), "r") do file
for line in eachline(file, keep=true)
occursin("<?xml", line) && continue
if occursin("<svg", line)
line = replace(line, ">"=>
"""width="$width" height="$height" style="display:inline; margin-left:1em; margin-bottom:1em">""")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-"""width="$width"
+""" width="$width"

elseif occursin("filter_beads_g", line)
line = replace(line, "filter_beads_g"=>"filter_"*id)
elseif occursin("</svg>", line)
text = """
<text x="16" y="1000" style="fill:black;opacity:0.9;font-size:80px;">$caption</text>
</svg>"""
line = replace(line, "</svg>"=>text)
end

m = match(r"data:image/png;base64,([^\"]+)", line)
if filter === nothing || m === nothing
write(io, line)
continue
end

head = m.offsets[1]
write(io, SubString(line, 1, head - 1))
src = IOBuffer(m.captures[1])
b64dec = Base64DecodePipe(src) # decode all for simplicity
b64enc = Base64EncodePipe(io)
write(b64enc, read(b64dec, 33)) # before the length of "PLTE"
replace_palette(b64enc, b64dec, filter)
n = write(b64enc, read(b64dec))
close(b64enc)
close(b64dec)
write(io, SubString(line, head + length(m.captures[1]), length(line)))
end
end
BeadsImageSVG(io)
end


function replace_palette(dest::IO, src::IO, filter)
buf = IOBuffer() # to calculate chunk CRCs

u8(x) = write(buf, UInt8(x & 0xFF))
u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
function read_palette()
uint32 = (UInt32(read(src, UInt8)) << 16) |
(UInt32(read(src, UInt8)) << 8) | read(src, UInt8)
reinterpret(RGB24, uint32)
end
function write_palette(c::Color)
rgb24 = convert(RGB24,c)
u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
end
crct(x) = (for i = 1:8; x = x & 1==1 ? 0xEDB88320 ⊻ (x>>1) : x>>1 end; x)
table = UInt32[crct(i) for i = 0x00:0xFF]
function crc32()
seekstart(buf)
crc = 0xFFFFFFFF
while !eof(buf)
crc = (crc>>8) ⊻ table[(crc&0xFF) ⊻ read(buf, UInt8) + 1]
end
u32(crc ⊻ 0xFFFFFFFF)
end
lenbytes = read(src, 4)
len = (UInt32(lenbytes[3]) << 8) | lenbytes[4]
write(dest, lenbytes)
write(buf, read(src, 4)) # "PLTE"
for i = 1:(len÷3)
write_palette(filter(read_palette()))
end
read(src, 4) # CRC
crc32()
write(dest, take!(seekstart(buf)))
end

end
17 changes: 16 additions & 1 deletion docs/src/advancedfunctions.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,22 @@ deuteranopic(c::Color, p::Float64)
tritanopic(c::Color, p::Float64)
```

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.
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*.

```@example deficiency
using Colors #hide
using Main: SampleImages # hide
SampleImages.BeadsImageSVG("Normal") # hide
```
```@example deficiency
SampleImages.BeadsImageSVG("Protanomaly (p=0.7)", filter=(c->protanopic(c, 0.7))) # hide
```
```@example deficiency
SampleImages.BeadsImageSVG("Deuteranomaly (p=0.7)", filter=(c->deuteranopic(c, 0.7))) # hide
```
```@example deficiency
SampleImages.BeadsImageSVG("Tritanomaly (p=0.7)", filter=(c->tritanopic(c, 0.7))) # hide
```

```@docs
protanopic
Expand Down
Loading