LoginSignup
2
3

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-08-12

はじめに

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

準備

PILの基本機能を確認してみます。

from PIL import Image

Image.open('imgae.png')
img.show()

上記を実行すると、image.png がデフォルトに設定されているソフトで画像が表示されます。

image.png
今回の生贄:嫁に描いてもらったオタサーの姫

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

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

gray.png
白黒になったオタサーの姫

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

rotate.png
回転したオタサーの姫

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

resize.png
小さくなったオタサーの姫

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

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

moza.png
18禁になったオタサーの姫

AA化

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

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の出来上がりという算段です。

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'MSP ゴシック', 5))

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

root.mainloop()

さて、上記から出来上がったのがこちら。
2019-08-12 (3).png
姫・・・?

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

最後に

AA職人はすごい!

2
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
2
3