ターミナル内で画像表示する手法についてかんがえる

はじめに

IT系のお仕事をしている人だと、ターミナルに住んでる人も少なくないのかなと思いますが、皆さんは画像を見るときどうしていますか? 「画像は普通にエクスプローラー(Finder)からプレビューで開いているよ」という人も多いかと思いますが、シェルから直接画像を閲覧できるターミナルエミュレータも世の中には存在しているのです。

今回は、ターミナル内で画像を表示させる手法についてよく使われているものをかんたんに整理してみました。

大きく分けて2つに分類できる

さて、画像をターミナル上で表示すると言っても、どのようなやり方があるのでしょうか? いろんなツールが世の中にあるようですが、大きく分けて2つに分類することが出来ます。

  1. 文字領域を画像のドットとして利用する場合
  2. ちゃんと画像として表示させる場合

文字領域を画像のドットとして利用する場合

昔から良くある方法ですね。 文字領域を画像のドットして利用して、アスキーアートで画像表示を行います。

比較的かんたんに試せるものだと、caca-utilsに入っているimg2txtが良いかなと思います。 なお、環境はUbuntu 22.10 LTSのシステムコンテナでテストをしています。

# caca-utilsをインストール
apt install caca-utils

# img2txtで画像を表示する
img2txt /path/to/file

画像ファイルとしてターミナル上に出力するわけではないため、大半のターミナルエミュレータで実行できるのが利点ですね。 ただし、当然画像としては荒くて正確に読み取れないというデメリットが大きく、あまり実用的ではないかもしれません。

ちなみに、あまり使いどころが無いと思いますがmplayerとcaca-utilsを組み合わせることで、ターミナルエミュレーター内で動画をアスキーアート変換して再生することも出来ます。 実務での使いどころがあまり想像出来ないところではありますが、面白いですよね。

ちゃんと画像として表示させる場合

次に、ターミナルエミュレーター上できちんと画像として表示してあげる場合。 これについては有名なプロトコルが2つあるので、ターミナルエミュレータ側が対応していれば画像をそのまま表示させることができます。

  1. Sixel ... VT200とかVT300の時代からあるプロトコルで、複数のターミナルが対応している。
  2. iTerm2 Image Protocol ... MacOS用のターミナルエミュレータである『iTerm2』が画像を表示するためのプロトコル。基本的にはiTerm2しか対応していない(後述)。

他にも似たようなプロトコルはあると思いますが、基本的にはこの2つのプロトコルがよく使われていると思います。

ターミナル上に画像表示するプロトコル『Sixel』

Sixelの概要

Sixel(Sixel Graphics)はVT200やVT300の時代からあるプロトコルです。 VT200やVT300というと1980年代なかばの頃なので、バブルより前からあったプロトコルなんですね。

縦横それぞれ6ピクセルの集合体をターミナル上で表示するための規格(Six Pixelの略でSixelになったらしい)で、Bitmap形式の画像をエンコードして表示させます。

参考

Sixelに対応しているターミナルエミュレータ

Sixelを使う場合、まずターミナルエミュレータ側が対応している必要があります。 残念なことにSixelに対応しているターミナルエミュレータは多くはなく、ディストリのデフォルトのターミナルは大体非対応。 たとえば、Ubuntuなどを何も考えずインストールしてすぐに使えるGnome Terminalなどは対応していません。

ざっと調べた限り、有名なものだと以下が対応している(実はiTerm2もSixelには対応している)。

  • mlterm
  • XTerm ... コンパイル時にオプション必要
  • RLogin
  • Alacritty ... Rust製のターミナルエミュレータ
  • wezterm ... Rust製のターミナルエミュレータ ← 今回の説明ではこれを使います

参考

実際に動かしているところを見てみよう

sixelを実際に使う場合、基本はlibsixelというパッケージに入っているimg2sixelコマンドを使うのが主流です ubuntuだとlibsixel-binに、Manjaroだとlibsixelでパッケージマネージャからインストールが行えます。 また、MacOSの場合でもbrewからlibsixelでインストール可能です。

# Ubuntuなどdebian系(debianの場合は`libsixel`だけでインストール可能かもしれません)
apt install libsixel-bin

# ManjaroなどArch系
yay -S libsixel

# MacOS
brew install libsixel

以下、実際に実行した結果です。 ターミナルエミュレータは、MacOS上のWezTermで、Ubuntuのシステムコンテナにログインして試しています。

img2sixel /path/to/file

このように、コマンドを実行直後に画像として表示されます。 Sixelで表示するにあたり一度bitmapに変換しているためか、透過pngだと背景が白塗りになるようですね。

iTerm2で独自に実装されたプロトコル『iTerm Image Protocol』

iTerm Image Protocolは、MacOSで使ってる人も多いターミナルエミュレータであるiTerm2に独自実装されている画像表示プロトコルです。

エスケープシーケンス後に画像データを表示することで、ターミナルエミュレータ側で画像を解釈して出力してくれるようなプロトコルになっています。 そのため表示のためのコマンドもshell scriptで実現できるて、かつssh先のサーバ上で利用する場合でもパッケージのインストールは不要となっています。 また、透過pngやGIFなどもそのまま表示してくれるため、Sixelよりも表示できるフォーマットは多いと思います。

↓の例では、MacOS上で動作しているUbuntuのシステムコンテナ上で、公式が用意しているimgcatコマンドを実行しています。

実は最近のバージョンであればiTerm2もSixelに対応しているのですが、昔からのiTerm2ユーザであればこちらのプロトコルを使ってる人のほうが多いんじゃないでしょうか。

WezTermは両方に対応している

実は今回Sixelの紹介で使用したWezTermですが、SixelとiTerm Image Protocolの両方に対応しています。

さいごに

いかがでしたでしょうか? 使う人はあまり多くなさそうなやり方ですが、意外とエクスプローラーとターミナルを行き来するのはまどろっこしい人も多いと思いますので、使ってみると意外と離れられなくなるかもしれませんね。

WezTermはMacでもLinuxでも、おそらくWindowsでも動くターミナルエミュレータなので、興味のある人はぜひ使ってみてください。

© 2016 - 2022 DARK MATTER / Built with Hugo / Theme Stack designed by Jimmy