Pythonで画像からアスキーアートを生成してみる

#はじめに
Pythonには画像処理のライブラリとして`PIL`があります。
今回は`PIL`を使って、画像からアスキーアートを作るプログラムを雑に作ってみます。

#準備
`PIL`の基本機能を確認してみます。

```python
from PIL import Image

Image.open('imgae.png')
img.show()
```
上記を実行すると、image.png がデフォルトに設定されているソフトで画像が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/104e168c-b7ae-62a2-206f-919ceef83479.png)
今回の生贄：嫁に描いてもらったオタサーの姫

また`.convert()`メソッドを用いることで画像を簡単に加工できます。

```python
gray = img.convert('L') #グレースケール化
gray.show()
```

![gray.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/0548b1f9-f8d0-8554-2338-7312691348a8.png)
白黒になったオタサーの姫

```python
rotate = img.rotate(90, expand=True) #90°回転
rotate.show()
```

![rotate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/36cfced8-9330-db94-024b-5797dc9c8284.png)
回転したオタサーの姫

```python
resize = img.resize((160, 128), Image.LANCZOS) #リサイズ
resize.show()
```

![resize.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/203b4b71-95fe-e53c-f4bb-0493b112fad7.png)
小さくなったオタサーの姫

この `.resize` を使うとかんたんなモザイク加工ができる。
極端に縮小をしてから元のサイズに拡大してあげればおｋ

```python
moza = img.resize([x // 32 for x in img.size]).resize(img.size)
moza.show()
```

![moza.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/57520931-c8c8-440e-8c18-22edb20111f8.png)
18禁になったオタサーの姫

#AA化
`.convert('L')`によって得られるグレースケール画像は、画像の各ドットごとに0～255の値を持った配列情報を持っています。
なので、'np.array'でその中身が見えます。
多分数値が大きいほど白(薄)く、0に近いほど黒(濃)い(はず

```python
from PIL import Image
import numpy as np

img = Image.open('image.png')
gray = img.convert('L')

gray_dot_array = np.array(gray)
print(gray_dot_array)
```

```
[[216 216 216 ... 216 216 216]
 [216 216 216 ... 216 216 216]
 [216 216 216 ... 216 216 216]
 ...
 [216 216 216 ... 216 216 216]
 [216 216 216 ... 216 216 216]
 [216 216 216 ... 216 216 216]]
```
配列になったオタサーの姫

各要素を255で割ってやれば0～1に正規化できるので、その値からAA化をしてみます。
要素の値の大きさによって、ドットを濃淡のある文字に置き換えて表示すれば濃淡AAの出来上がりという算段です。

```python
from PIL import Image
import numpy as np
import tkinter as tk

root = tk.Tk()

img = Image.open('image.png')
resize = img.resize((100, 80), Image.LANCZOS) 
gray_img = resize.convert('L')

img_dot_array = np.array(gray_img)
norm_img_array = img_dot_array / 255

img_ascii = {}
img_label = {}

for i in range(0, gray_img.size[1]):
  for j in range(0, gray_img.size[0]):
      if j == 0:
          if norm_img_array[i,j] > 0.9:
              img_ascii[i] = "米"
          elif norm_img_array[i,j] > 0.8:
              img_ascii[i] = "髟"
          elif norm_img_array[i,j] > 0.7:
              img_ascii[i] = "面"
          elif norm_img_array[i,j] > 0.6:
              img_ascii[i] = "鼎"
          elif norm_img_array[i,j] > 0.5:
              img_ascii[i] = "蠻"
          elif norm_img_array[i,j] > 0.4:
              img_ascii[i] = "鬣"
          elif norm_img_array[i,j] > 0.3:
              img_ascii[i] = "麌"
          elif norm_img_array[i,j] > 0.2:
              img_ascii[i] = "黌"
          elif norm_img_array[i,j] > 0.1:
              img_ascii[i] = "鬱"
          else:
              img_ascii[i] = "䨻"
      else:
          if norm_img_array[i,j] > 0.9:
              img_ascii[i] = img_ascii[i] + "米"
          elif norm_img_array[i,j] > 0.8:
              img_ascii[i] = img_ascii[i] + "髟"
          elif norm_img_array[i,j] > 0.7:
              img_ascii[i] = img_ascii[i] + "面"
          elif norm_img_array[i,j] > 0.6:
              img_ascii[i] = img_ascii[i] + "鼎"
          elif norm_img_array[i,j] > 0.5:
              img_ascii[i] = img_ascii[i] + "蠻"
          elif norm_img_array[i,j] > 0.4:
              img_ascii[i] = img_ascii[i] + "鬣"
          elif norm_img_array[i,j] > 0.3:
              img_ascii[i] = img_ascii[i] + "麌"
          elif norm_img_array[i,j] > 0.2:
              img_ascii[i] = img_ascii[i] + "黌"
          elif norm_img_array[i,j] > 0.1:
              img_ascii[i] = img_ascii[i] + "鬱"
          else:
              img_ascii[i] = img_ascii[i] + "䨻"

for i in range(0, gray_img.size[1]):
   img_label[i] = tk.Label(text=img_ascii[i], font=(u'ＭＳＰ ゴシック', 5))

for i in range(0, gray_img.size[1]):
    img_label[i].pack()
   
root.mainloop()
```

さて、上記から出来上がったのがこちら。
![2019-08-12 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438971/522c64cf-8cf5-f956-4927-190346834d2b.png)
姫・・・？

遠くから見れば姫に見えなくもないけどよくわからないですね。。

#最後に
AA職人はすごい！