本日は
- よく知られているように(?) Mac でよく使われる iTerm2 では
imgcat
というコマンド を用いて画像をターミナルの上でプレビューすることができます.
- SixelGraphics に対応していれば iTerm2 以外でもできます:
こんな感じのことを Julia の REPL でもしたいですよね? もちろん REPL の Julian mode から Shell mode へ遷移してやることもできます.
julia> # これが Julian mode
julia> ; # ここでセミコロンを入力
shell> # これがシェル
shell> ls
sin.png
shell> imgcat sin.png
shell> # Ctrl-C を入力して Julian mode に遷移する
julia> # 戻ってきた
が,これをするには REPL のモードを変更する必要があり一手間かかります. Julian mode の状態 (julia>
) で直接描画できないのでしょうか?
REPL でもできらぁ!
ここで Sixel.jl に登場してもらいます. そうすると下記のようになります:
できてますね. (testimage
関数の呼び出しでエラーが起きた場合は pkg> add ImageIO
をやってみてください)
sixel_encode
は using Sixel
とロードすることで使えます. この関数の入力の型は RGB{N0f8}
を要素とする配列を受け付けることができます. Images.jl をはじめとるす Julia 画像処理周りでよく出てきます.
julia> m = testimage("mandril_color")
512×512 Array{RGB{N0f8},2} with eltype ColorTypes.RGB{FixedPointNumbers.N0f8}:
RGB{N0f8}(0.651,0.545,0.243) RGB{N0f8}(0.22,0.188,0.137) … RGB{N0f8}(0.671,0.741,0.443)
RGB{N0f8}(0.416,0.451,0.196) RGB{N0f8}(0.545,0.392,0.169) RGB{N0f8}(0.459,0.486,0.224)
RGB{N0f8}(0.294,0.251,0.125) RGB{N0f8}(0.482,0.42,0.188) RGB{N0f8}(0.38,0.29,0.157)
RGB{N0f8}(0.227,0.29,0.176) RGB{N0f8}(0.541,0.518,0.212) RGB{N0f8}(0.196,0.29,0.165)
RGB{N0f8}(0.384,0.286,0.165) RGB{N0f8}(0.549,0.482,0.2) RGB{N0f8}(0.282,0.325,0.157)
RGB{N0f8}(0.286,0.29,0.125) RGB{N0f8}(0.282,0.294,0.125) … RGB{N0f8}(0.671,0.741,0.451)
⋮ ⋱
RGB{N0f8}(0.388,0.38,0.384) RGB{N0f8}(0.345,0.412,0.482) RGB{N0f8}(0.255,0.294,0.263)
RGB{N0f8}(0.322,0.357,0.29) RGB{N0f8}(0.349,0.416,0.478) RGB{N0f8}(0.286,0.294,0.251)
RGB{N0f8}(0.353,0.416,0.478) RGB{N0f8}(0.443,0.514,0.514) RGB{N0f8}(0.294,0.314,0.329)
RGB{N0f8}(0.455,0.541,0.631) RGB{N0f8}(0.451,0.58,0.506) RGB{N0f8}(0.29,0.294,0.224)
RGB{N0f8}(0.451,0.588,0.667) RGB{N0f8}(0.455,0.537,0.62) … RGB{N0f8}(0.251,0.224,0.251)
RGB{N0f8}(0.451,0.588,0.667) RGB{N0f8}(0.455,0.537,0.62) RGB{N0f8}(0.251,0.224,0.251)
グレースケールのも対応しています:
こんな感じでお使いのターミナルがリッチな表現に対応していれば Julia の REPL上でもいい感じにできます.
グラフのプレビューできます?
Plots.jl の結果を REPL で確認したいですよね? もちろん UnicodePlots.jl をバックエンドとして使うこともできます.
できますが, もっとカラフルに見せたいところです.
できらぁ!
下記のコードをコピーして REPL に貼り付ければOKです.
using FileIO, Sixel, Plots
gr()
buf = IOBuffer()
show(buf, MIME("image/png"), plot(sin, size=(1000, 750)))
buf |> load |> sixel_encode
-
show
関数でplot(sin)
というプロットオプジェクトを png にて保存するために必要なデータを出力させます. このMIME
は
マルチパーパス・インターネット・メール・エクステンションの略です. Julia のオブジェクトがどのように表示されるのか・どのロジックを選択するのかを知るにはYouTube のリンクの説明がわかりやすいです. 英語を翻訳した日本語字幕も表示させることができます.
- さて,show 関数によって出力されたデータはディスクにダンプさせる(= savefig などでファイルに一旦保存する)のではなく, メモリに上に乗っけておきます. 出力を流し込む先を標準出力 stdout ではなく
buf=IOBuffer()
オブジェクトに出力を流しておきます. - さらに
buf
に格納されたデータをFileIO.load
関数で読み込みます. その結果をsixel_encode
でエンコードすればめでたしめでたし.
ローカルのファイルを読み込んで表示
もちろんファイルに保存している png データを読み込んで表示させることもできますね.
素晴らしい.
sixel_encode
の入力がめんどくさい?
何回も sixel_encode
を入力するのが面倒な場合は ImageInTerminal.jl をロードすることで解決できます. これにより 画像オブジェクトを REPL での表示を要素を表示するテキストのものからリッチにな表示にするように内部で表示をコントロールしてくれます.
Appendix
お使いのターミナルがうまく表示されない?
例えば Mac デフォルトの Terminal
だと少し残念な表示になります.
これはデフォルトのターミナルが sixel format に対応してないからです.
リッチにプレビューしたい場合は下記の関数が true
を返す必要があります.
julia> Sixel.is_sixel_supported()
false
万が一 true
にもかかわらず表示がリッチにならない場合は Sixel.jl にバグレポートを出すと良いでしょう.