Operation KiWi

一生使える言語はPythonだと信じてる

Python3.6.1で画像をアスキーアート(AA)に変換するプログラムを書いた

f:id:sakage24:20170708000950j:plain

何に見えますか?

一体どういう層に需要があるのか分かりませんが、githubに眠っていたので日の目を浴びさせる目的で公開します。

作ったきっかけ

RPG内の敵表示にでも使えるかな~

私が作成してたゲームは、コンソールで動いているゲームなので、画像、スプライトなどは使えません。少しでも視覚的に見やすくて楽しい表示方法って無いかな…と思っていたのですが、AAで表示するのが一番いいのかな?と思いました。

とりあえず、色々ググってみた結果、結構先駆者の方がいました。私の場合txt形式に保存したかったので、一部改造して使わさせていただきました。ありがたや。

一応出来たはいいのですが、精度を求めて画像の粒度を大きすぎるとおかしくなるし、粒度が小さいと何が何だか分からないというジレンマに苦しみましたw難しいですね…実践投入はまだまだ先になりそうですw

ソースコード

import os
from PIL import Image
import sys


def create_aa(img):
    width = img.size[0]
    height = img.size[1]
    input_pix = img.load()
    character = ""
    aa_list = []
    div = 48
    try:
        val = int(sys.argv[1])
        if val > width:
            div = width
        else:
            div = val
    except (IndexError, ValueError):
        pass
    size = width // div
    for i in range(0, height, size):
        for j in range(0, width, size):
            r, g, b = input_pix[j, i]
            gray = r * 0.2126 + g * 0.7152 + b * 0.0722
            if gray > 250:
                character = "  "
            elif gray > 230:
                character = "・"
            elif gray > 215:
                character = "’"
            elif gray > 200:
                character = ":"
            elif gray > 185:
                character = ";"
            elif gray > 160:
                character = "="
            elif gray > 145:
                character = "+"
            elif gray > 130:
                character = "i"
            elif gray > 115:
                character = "t"
            elif gray > 100:
                character = "i"
            elif gray > 85:
                character = "Y"
            elif gray > 60:
                character = "V"
            elif gray > 45:
                character = "X"
            elif gray > 30:
                character = "R"
            elif gray > 15:
                character = "B"
            elif gray > 0:
                character = "M"

            aa_list.append(character)
        aa_list.append("\n")
    return aa_list


def trans_aa():
    mod_name = ""
    for lists in file_lists:
        input_image = Image.open("picture/" + lists)
        m = lists[::-1]
        for index, x in enumerate(m):
            if x == ".":
                mod_name = m[index + 1:]
                break
        output_image = create_aa(input_image)
        with open("result/" + mod_name[::-1] + ".txt", "wt", encoding='utf-8') as fout:
            for x in output_image:
                fout.write(x)
    input("変換が完了しました!")


def exists_dir():
    if not os.path.exists("picture"):
        os.mkdir("picture")
    if not os.path.exists("result"):
        os.mkdir("result")

if __name__ == "__main__":
    # ディレクトリ作成
    exists_dir()
    file_lists = os.listdir("picture")
    try:
        if file_lists:
            trans_aa()
        else:
            print("ファイルが存在しません!")
            input()
    except ValueError:
        print("ファイル形式に対応していません。")

実行結果

元画像

f:id:sakage24:20170707233715j:plain *1

結果(小さめ) 10 × 10

+++i++++t+i
iViV+iiViVi
iViMViV:VVi
VVVXVVBV:Vi
VVVM::i・BMi
VV:BB・・:M;i
  VM・=・・・・・i
  VV・・・・・・M+
  ・VV・・・・・=V
      +V  ・・=’i
      RYYM=’MY

何が何だかww

結果(大きめ) 48 × 48

+++++++++++++++++ii+++++++++++++i++++++i+++iiiMiiiiii
+++++++++i+++++++ii+++++++i+++++ii++++++MViiiiV+iiiii
++++++i+i++++++i+iii+++++++i+++++VV++tii+MVXiiVMiiiii
ii++i+i++++++t+i+iii+++++i+iiiMiiVVV++ii+iBYiiVViiiii
it++i+iiiiiiiMiVRVVV+i+++i+iViiMiiVVV++iiiiViiVV+iiii
iii+iiiiiiiiiMiVMiMVi++i+ii+iViiViiVVVi+iiiXBiiV+iiii
i+ii+ViiiiiiiYiV:iVVV+iiiiiViiVtiViVVVVViiiiVViVYiiii
iiii+ViiiiiiViiV;iVVViiiiiiiViVViiViVVVVV+iiVBiVMiiii
iiii+ViiiiiVViiV:MVBVV+iiiiiVViVViMVVVVVVViiiMVVViiii
iiiiiViiiiiiViiV::iVVViiiiViMVViVVi:VVVVVVViiVVVViiii
iii+VViiiiiiViiV::iVVVV+iiiViVVVVVVi:BVVVVVViVMVV+iii
iii+VViiMiiiVMiV::iVVVViiiiViMVVVVVVM:;RVVVVVVVVV+iii
iii+VViVMiiiVMiV:::VVVVV+iiiViVVVVVVV::MMMVVVVVVV+iii
Vii+VViVMiiiiBiV:::・VRVVViiiVVMVVVVVRV;:::VVVVVVVMiii
Vii+VViVMiVii:ii:::・VVMVViiiiMV:VMVVVVM::::VVVVMV+iii
ViiiVViVMiVii:ii:::・・VVBVViiiVVM:VVVVVV’:;::VVVMVXiii
ViiVVViVMiVVM:ii’MM・・BVMVVViiiMV::MVVVVM・::::VVVVMiii
ViiVVViVVMVVi:Mi・::・・・VV:VVViiVVM::・VVVV・・・::BVVVMiii
ViiVVVVXViVVM:・iM::・・・・VMBVViiiMV’’:・VVVV・・・::BVVMiii
ViiVVVVVViVVM:・iM・::・・・MV:MVViiV;V・::’’VVMMMMM:VMMVii
VViVVVVVVMVVM:・・Y・:::・・・VB:MVVii::・:・・MMMMMMMMMM:YVii
VViVVVVVVMVVM:・・i・・:M・・・・V::MVViV:・’MMMMBBBBBMMM:iiii
VViVVVVVVVVVM:・MMMM・・;・・・・V;:・VVi::’MMBBBBBBBBMMM+iii
MViVVVVVV:MVM:MMMMMMM・・・・・・V・:・ViM:・M;B・BBMBBBBM・iiii
VVVVVVMVV::VVMMMBBBBMMM・・・・・M・:’Vi::・;BBMMMMBBBMMiiii
VVVVVVBVV:::VMMBBBBBBBM・・・・・・・・・・B・:・;BBBMMMBB;Mtiiii
VMViVVVVVM::MMMBB・BBBBM・・・・・・・・・・・・・・・BBBMMMRR;M・iiii
VVVVVVVBVM::MM;BBBMMMRB・・・・・・・・・・・・・・・B・BBBB=B・・・Viii
VVMVVVVVVV;:MM;BBBMMMVB;・・・・・・・・・・・・・・・・;XX=・B  ・+Viii
VVVVVVVVRVM::MM;BBBMB+B・・・・・・・・・・・・・・’・Ri;;;X・・・MViii
BiV+VVVVVVBY:・・;VB・BV==・・・・・・・・・・・・・・・・BBBBMM’・・iViii
  MViBVVVVVVV:・・・・・  :=+B・・・・・・・・・・・・・・・・・・・・・・・・・iViii
    iViVVVBVVMV・・・・  BVVM・・・・・・・・・・・・・・・・・・・・・・・・・・MViii
      MiVVVVVVVMX・・’・MM・’・・・・・:’・・・・・・・・・・・・・・・・・・・:Yiii
      BiVXVVVVVVR・・・・・・・・・・・・・:;’・・・・・・・・・・・・・・・・・M:iiii
    M  XVVRVVVVVVX・・・・・・・・・・・・::・・・・・・・・・・・・・・・・・・M:iii+
    B  MVVVMVVVVVV’・・・・・・・・・・・・・t・・・・・・・・・・・・・・・・・::iii+
          VVVVVVVVVV’・・・・・・・・・・・・・’・・・・・・・・・・・・・・・・・:MiiiM
      ・  VVVXVVVVVVV・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・;:ViiiV
          VVV  VViVVVB’’・・・・・・・・・・・・・・・・・・・・・・・・・・・:;MViiiV
      M  VVV  VVViVVVV・’・・・・・・・・・・・・X・t・・・・・・・・・・・:M=Vii+V
      B  ・VV    VViiVVVV・・・・・・・・・・・・・・’・・・・・・・・・・・:M==ViiMV
            VVM  BViiVVMBVM・・・・・・・・・・・・・・・・・・・・・・・:M==;MiiMV
            MVM    ViiiVVMVVMB・・・・・・・・・・・・・・・・・・・・:====MMiiVV
              VX      ViiVVV:VV・  M・・・・・・・・・・・・・・・・・M====;VMiiVi
              MV      Bii+VV  VV        B・・・・・・・・・・・・・・======’’iiMVi
            ・  V        ViiVV    VV        BM・・・・・・・・・・t;=====’M’iiVVi
                MM        iiVM      V          VM・・・・・・・M=======’’’’iiVVi
                  R        Bi+B        :    YYMVYM・・・M========’’’’’i’VVi
                              V+          ・MYYYMYYMYYY;=======’’’’’Mi’Vii
                                +  MMRRMYYYYBYYYYYYY=======’’’’’i=’ViR
                            Mt+RRRRYYYYYYYYYYYYM=M=====’’’’’’i’MiiY
                        MitRMRRMYYYYYYYYYYY=========’’’’’’’’’Vi’Y

ちょっと離れたら分かりますかね?

終わり

まあPythonってこんなことも出来るのかくらいに捉えて頂ければ幸いです。

参考URL

d.hatena.ne.jp

こちらのブログの記事が大変参考になりました。