Copyright (c) 2020 Lirimy
Released under the MIT license
https://opensource.org/licenses/MIT
Julia で画像を直接扱う場合、型でいうと AbstractMatrix{<:Colorant}
を使うことになる。
Colorant
は ColorTypes.jl で定義されている。
using ColorTypes, FileIO
色の配列を PNG に変換するためには
のいずれかが必要。add するだけで、using はしない。FileIO を通して変換する。
ドキュメントの更新が遅れているようで ImageIO は記載されていないが、ソースコードが正しい。
https://github.com/JuliaIO/FileIO.jl/blob/master/src/registry.jl#L91
https://github.com/JuliaIO/FileIO.jl/blob/master/docs/registry.md
]st ImageIO
Status `C:\Users\Lirimy\.julia\environments\v1.5\Project.toml` [82e4d734] ImageIO v0.3.0
まずは PNG を表示できるようにする。コンストラクタで多重ディスパッチすることで、
からオブジェクトを生成できる。
struct PNG{T}
data::T
end
PNG(filename::AbstractString) = read(filename) |> PNG
function PNG(img::AbstractMatrix{<:Colorant})
buf = IOBuffer()
save(Stream(format"PNG", buf), img)
take!(buf) |> PNG
end
function Base.show(io::IO, ::MIME"image/png", p::PNG)
write(io, p.data)
flush(io)
end
hcat(
fill(rand(RGB), 240, 100),
fill(rand(RGB), 240, 100),
fill(rand(RGB), 240, 100)
) |> PNG
次に、色の配列を表示する際の、 PNG オブジェクトへの変換を見えなくする。
Colors.jl で定義されている "image/svg+xml" に対する show が有効で、
"image/png" よりも優先されてしまうので無効化する。
https://github.com/JuliaImages/ImageShow.jl/blob/master/src/showmime.jl#L18
ImageIO.jl -> PNGFiles.jl -> ImageCore.jl -> Colors.jl の経路か?
無効化することにより、 display(MIME("image/png"), img)
と書かなくてすむ。
Base.showable(::MIME"image/svg+xml", ::AbstractMatrix{<:Colorant}) = false
function Base.show(io::IO, mime::MIME"image/png", img::AbstractMatrix{<:Colorant})
show(io, mime, PNG(img))
end
img = fill(rand(RGB), 240, 300)
img[30:180, 50:200] .= rand(RGB)
ix = filter(CartesianIndices(img)) do cix
i, j = cix.I
(i-150)^2 + (j-200)^2 < 80^2
end
img[ix] .= rand(RGB)
img
MIME("text/html")
を定義するならば、優先度が高いため SVG を無効化しなくてもよい。
ただし、Jupyter は利用可能な MIME のデータをすべて保持するので、ノートブックの容量が増大することに留意する。
https://jupyter-client.readthedocs.io/en/stable/messaging.html#id4
using Base64
function Base.show(io::IO, ::MIME"text/html", p::PNG)
write(io, "<img src=\"data:image/png;base64,")
enc = Base64EncodePipe(io)
write(enc, p.data)
close(enc)
write(io, "\" />")
flush(io)
end
function Base.show(io::IO, mime::MIME"text/html", img::AbstractMatrix{<:Colorant})
show(io, mime, PNG(img))
end
img