LoginSignup
18
8

More than 3 years have passed since last update.

文字を gnuplot で3次元表示するシェル芸

Last updated at Posted at 2020-01-28

文字の3次元表示

文字を3次元表示するというのは、たとえば
🤔
↑この絵文字から、
↓この画像を生成する
x.png
というようなことを指します。
やっていきましょう。

コマンド

これを実現するコマンドは以下。

$ echo -e "\n🤔 "|textimg -F300|convert - -trim -scale 300x300! -flip -compress none pgm:-|tail -n +4>x;gnuplot -e "set term png;set output '/images/x.png';set xr[0:300];set yr[0:300];set view 30,30,1,1;splot 'x' matrix with pm3d"

これでパス /images/x.png に画像が書き込まれます。

前提条件

textimg, imagemagick, gnuplot がインストールされていること。

解説

コマンドをよく見ると、実はコマンド一発のシェル芸ではなく、
2つのコマンドを;でつないだものになっています。
前半部、後半部に分けて見ていきましょう。

前半部解説

前半部は以下。

$ echo -e "\n🤔 "|textimg -F300|convert - -trim -scale 300x300! -flip -compress none pgm:-|tail -n +4>x

まず echo -e "\n🤔 "|textimg -F300 で、以下の画像が生成されます。
0.png
"改行+🤔+半角スペース"の文字列を、
textimg -F300 でフォントサイズ300ポイントで描画しています。
絵文字の上と右に黒いスペースを入れているのは、これを入れないと
textimgで絵文字の上と右の端が切れてしまうからです。
そしてこれを convert に入力して、
convert - -trim -scale 300x300! -flip
として整形します。
1.png
周囲の黒い部分をトリムして、300x300 にリサイズして、
上下反転しています。
上下反転の理由は後半部で説明します。
convert コマンドには続きのオプションがあります。
-compress none pgm:- として、
無圧縮pgmフォーマットで出力しています。
無圧縮pgmで出力すると何が出力されるかというと、
300x300の無圧縮pgmをそのままここに表示すると、
場所を取りすぎますので、小さめのサイズで表示してみます。

$ echo -e "\n🤔 "|textimg -F300|convert - -trim -scale 10x10! -flip -compress none pgm:-
P2
10 10
255
19 131 154 106 108 111 82 23 0 0 
90 194 207 203 168 171 171 163 66 0 
113 211 217 201 166 173 173 173 168 41 
134 189 183 196 203 179 190 190 190 123 
146 196 208 204 191 194 196 208 208 172 
148 218 218 151 112 116 213 218 218 181 
112 219 219 218 216 206 110 215 219 144 
36 205 216 68 187 197 69 211 212 60 
0 80 204 118 198 200 178 196 104 1 
0 0 38 158 141 165 127 48 0 0

10x10の画像を無圧縮pgmフォーマットで出力してみました。
上のようなテキストが出力されます。
テキストの意味を見ていきましょう。
最初の3行の

P2
10 10
255

の部分は、10x10のサイズで、画素値の最大値が255のグレイスケール画像であることを示しています。
ヘッダのあとの、10行x各行10個の数値列が各ピクセルの画素値です。
元のコマンドの

$ echo -e "\n🤔 "|textimg -F300|convert - -trim -scale 300x300! -flip -compress none pgm:-

では、これが300x300で出力されるわけです。
そしてこれをtail -n +4>xに渡すと、ヘッダ部分が削除されてxというファイルに書き込まれます。
300行、各行300個のピクセル値がxに書き込まれました。
これで前半部終了です。

後半部解説

後半部のコマンドは以下

$ gnuplot -e "set term png;set output '/images/x.png';set xr[0:300];set yr[0:300];set view 30,30,1,1;splot 'x' matrix with pm3d"

gnuplot を用いて
splot 'x' matrix with pm3dで、ファイルxのデータを3次元表示します。
このとき、無圧縮pgmのy軸が画像の上から下へ向かう方向が正方向であるのに対して、
gnuplotでは下から上が正方向なので、前半部で上下反転しているわけです。
結果、以下の画像が生成されます。
x.png

別解

textimg を使わないバージョン。

$ echo "digraph{🤔[label=\"\\n🤔\" fontsize=300 shape=none style=filled fillcolor=black]}"|dot -Tpng|convert - -shave 10x10 -trim -scale 300x300! -flip -compress none pgm:-|tail -n +4>x;gnuplot -e "set term png;set output '/images/x.png';set xr[0:300];set yr[0:300];set view 30,30,1,1;splot 'x' matrix with pm3d"

文字から画像を生成するために、graphviz を使っています。

所感

今朝これをシェル芸botでやったところ、反響が大きかったので簡単にまとめてみました。
今日一日、シェル芸botからこういう画像がたくさん流れて来て、
画像シェル芸ってふだんあまりマネしてもらえないので、嬉しいです。

18
8
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
18
8