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

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

コメントを残す

メールアドレスが公開されることはありません。