8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JuliaAdvent Calendar 2021

Day 11

Julia の REPL ででも画像をリッチにプレビューしたいんです(Sixel.jl 入門).

Last updated at Posted at 2021-12-10

本日は

  • よく知られているように(?) Mac でよく使われる iTerm2 では imgcat というコマンド を用いて画像をターミナルの上でプレビューすることができます.

image.png

こんな感じのことを 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> ) で直接描画できないのでしょうか? :thinking:

REPL でもできらぁ!

ここで Sixel.jl に登場してもらいます. そうすると下記のようになります:

image.png

できてますね. (testimage 関数の呼び出しでエラーが起きた場合は pkg> add ImageIO をやってみてください)

sixel_encodeusing 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)

グレースケールのも対応しています:

image.png

こんな感じでお使いのターミナルがリッチな表現に対応していれば Julia の REPL上でもいい感じにできます.

グラフのプレビューできます?

Plots.jl の結果を REPL で確認したいですよね? もちろん UnicodePlots.jl をバックエンドとして使うこともできます.

image.png

できますが, もっとカラフルに見せたいところです.

できらぁ!

image.png

下記のコードをコピーして 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 データを読み込んで表示させることもできますね.

image.png

素晴らしい.

sixel_encode の入力がめんどくさい?

何回も sixel_encode を入力するのが面倒な場合は ImageInTerminal.jl をロードすることで解決できます. これにより 画像オブジェクトを REPL での表示を要素を表示するテキストのものからリッチにな表示にするように内部で表示をコントロールしてくれます.

image.png

Appendix

お使いのターミナルがうまく表示されない?

例えば Mac デフォルトの Terminal だと少し残念な表示になります.

image.png

これはデフォルトのターミナルが sixel format に対応してないからです.
リッチにプレビューしたい場合は下記の関数が true を返す必要があります.

julia> Sixel.is_sixel_supported()
false

万が一 true にもかかわらず表示がリッチにならない場合は Sixel.jl にバグレポートを出すと良いでしょう.

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?