サーバーログイン時に超力技でドット絵を表示する

会社の勝手サーバーにログインした時にドットのロゴが表示されるようにしたところ、
割と好評？というか話題になったので、今度は調子こいてドット絵にしてみようと思います。
ログイン時の表示は、/etc/motdに記載することによって実装します。

## ドット絵を作る手段
とはいえ、一からドット絵を作るのは面倒くさい…ネットに転がってる画像を解析とか出来ないんだろうか…。
そういえばこの前、@m-daichangと画像処理の方法を話していた時、
「Solarisインストール時にImageMagickとかいうジジイがマスコットのソフト見かけたからそれでいいのでは？」
とm-daichangに言ったことを思い出しました。(尚、その提案はあっさり却下されました)

ということで、ImageMagickで調べたら、[ここ](https://uec.usp-lab.com/JOURNAL/CGI/JOURNAL.CGI?POMPA=KAIGAN_journal15)とか[ここ](http://blog.awm.jp/2016/01/04/pnm/)に遭遇しました。
どうやらImageMagickでいけそうです。

## ImageMagickの入手

普通に```yum -y install ImageMagick```です。
こんな感じでバージョン表示できればOKです。

```
# convert -version
Version: ImageMagick 6.7.8-9 2016-06-16 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC
```

尚、わたくしの利用したOSは```CentOS Linux release 7.1.1503 (Core)```です。

## ドット絵を入手してppm形式にする
ドット絵は、適当にググって入手して下さい。
*ヒント：海外でドット絵は「sprite」と言うそうです。海外版のファミコンは「NES」ですね。*

CUI上の1マスが縦長なので、今回は1マスを0.5dotとして扱います。
従いまして、1dot=1x1pixelの画像が良いです。1dot=2x2pixelだとでかくなりすぎます。
imagemagickでサイズ変更は出来ますが、色がにじんでしまうでダメです。

今回はこんなのを入手しました。
![air.png](https://qiita-image-store.s3.amazonaws.com/0/161568/04c0a19d-862d-a4b1-1589-0d971761b7dc.png)

これをppm形式にします。ppmというのは、portable pixmap formatの略で、PNM(*Portable aNyMap*)の一種です。
このフォーマットの特徴として、画像データをASCIIで扱えることがあげられます。

```
# convert air.bmp -compress none air.ppm
```

上記の通りコマンドを実行すると、中身ASCIIの画像データが出来ます。
-compress noneを指定しないと、中身がbinaryになってしまうので注意です。

## PPMの中を見てみる

```
# head air.ppm
P3
37 30
255
255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255
255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 255 0 255 0 0 0 0 0 0 0 0 0
(略)
```

一行目はPNMの種類を表すマジックナンバーで、PPMのASCIIであることを表しています。
二行目はWidth(columns) Height(rows)です。
三行目は色を表す数値の最大値です。
ここから、RGBを抽出していきます。

## PPMの中身からRGBを抽出してANSI Colorに置き換えて出力する
以下のようなスクリプトで抽出置換します。

```bash:make_sprite_motd.sh
     1  #!/bin/bash
     2 
     3  ppm="air.ppm"
     4  transparent_before="255;0;255"
     5  transparent_after="32;32;32"
     6 
     7  read cols rows <<<$(sed -n '2p' ${ppm})
     8 
     9  set $(sed -n '4,$p' ${ppm})
    10  {
    11  for i in $(eval echo {1..${#}..3})
    12  do
    13    j=$((i+1))
    14    k=$((i+2))
    15 
    16    rgb="${!i};${!j};${!k}"
    17    if [ ${rgb} == ${transparent_before} ] ; then
    18      rgb=${transparent_after}
    19    fi
    20 
    21    if [ $(( (${i} + 2) / 3 % ${cols} )) -eq 0 ] ; then
    22      echo -e "\033[48;2;${rgb}m  \033[m"
    23    else
    24      echo -en "\033[48;2;${rgb}m  \033[m"
    25    fi
    26  done
    27  } >/etc/motd
    28
    29  exit 0
```

ANSI Colorについては[ここ](https://en.wikipedia.org/wiki/ANSI_escape_code)を読んでください。(ただのwikiですが)
以下、スクリプトの簡単な解説です。

4,5 : 透過色が派手なこともあるので、好きな色に置換するために用意してます。
7 : 列を取得してきています。この数値でいつ折り返すかを計算します。行は特に使いません。
9 : ppmの4行目以降を位置パラメータに展開しています。
11 : 3つ1セット(rgbなので)で処理したいので、この書き方になっています。
17-19 : RGBが透過色の場合は置換します。
21-25 : cols列目で折り返すための処理です、折り返し=改行なので、`echo -en`と`echo -e`で分岐してます。

引数で画像のパスを渡すと、それを変換してmotdに出力するバージョンも[作りました](https://github.com/hasegit/shellscript/blob/master/dot_to_motd.sh)ので、ご参考にどうぞ。

## motdを設定した結果
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/161568/686d7a3c-7010-67cc-6c5f-05635a3816d2.png)

**デカアァァァァァいッ説明不用!!**

## おまけ
2017/03/21追記

TeraTermのフォントを[RictyDiminished](https://github.com/edihbrandon/RictyDiminished)とかにして
font-size11位にすれば、デカアァァァァァいッまではいかないかも。
(設定→その他の設定→表示→フォントの品質をアンチエイリアスにするのを忘れずに)
10以下だと老眼殺しになるのでちょっとつらい…。

あと、それなりに色は出せるので、色の少ないファミコンにこだわらない方がよろしいかも。
色数多いほうがなんとなくぼやけてアラが目立たないというか…。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/161568/175129b8-a41b-7972-f216-551920fa3946.png)