Python アスキーアートを作った - 2

Converted a image to an ascii art
前回記事: Python アスキーアートを作った


改良したコードはこちら。python3.4にて。




 
#!/usr/bin/python

from PIL import Image, ImageDraw, ImageFont
import os

class Image2ascii():
    def __init__(self, filename):
        self.filename = filename
        self.input_image = Image.open(filename)
        self.w, self.h = self.input_image.size
    def set_size(self,w,h)
        self.w, self.h = w, h

    def set_output_image(self):
        self.output_image = Image.new(mode='RGBA', size=(self.w,self.h), color=(255,255,255)) # check variations

    def set_font(self, font="C:\\Windows\\Fonts\\msgothic.ttc", fontsize=23, encoding='utf-8'):
        self.font = font
        self.fontsize = fontsize
        self.encoding = encoding
        self.font = ImageFont.truetype(font=self.font, size=self.fontsize, encoding=self.encoding)

    def set_draw(self):
        self.draw = ImageDraw.Draw(self.output_image)

    def set_text_in_output_image(self, ascii='W#%*+;:,.  ', color='color'):
        self.color=color
        self.input_pix = self.input_image.load()
        for y in range(0, self.h, self.fontsize):
            for x in range(0, self.w, self.fontsize):
                r,g,b = self.input_pix[x,y]
                gray = r*0.2126 + g*0.7152 + b*0.0722
                character = ascii[int(gray//25)]
                if self.color == 'color':
                    self.draw.text((x,y),character,font=self.font,fill=(r,g,b))
                elif self.color == 'monotone':
                    self.draw.text((x,y), character,font=self.font,fill='#000000')
                else:
                    print('the variable color takes color or monotone')
                    break
                if x >= self.w-self.fontsize:
                    print(character, end='\n')
                else:
                    print(character, end='')
                    
    def save_output_image(self):
        filename = os.path.basename(self.filename)
        if self.color == 'monotone':
            self.output_image.save(os.path.splitext(filename)[0]+'_Ascii'+''.join(self.font.getname()).replace(' ', '')+str(self.fontsize)+'.png')
        elif self.color == 'color':
            self.output_image.save(os.path.splitext(filename)[0]+'_AsciiColor'+''.join(self.font.getname()).replace(' ', '')+str(self.fontsize)+'.png')
        else:
            print('the variable color takes color or monotone')
    def show(self):
        self.output_image.show()        

if __name__=='__main__':
    image2ascii = Image2ascii('Leonardo_da_Vinci_(1452-1519)_-_The_Last_Supper_(1495-1498).jpg')
    image2ascii.set_size()
    image2ascii.set_output_image()
    image2ascii.set_font(fontsize=23)
    image2ascii.set_draw()
    image2ascii.set_text_in_output_image(ascii='W#%*+;:,.  ',color='monotone')
    image2ascii.save_output_image()
    image2ascii.show()


  輝度を0 to 255を25ごとに区切り、輝度の低いところから、
W#%*+;:,.
という具合に、Wから空白スペースまでを対応させている。
  カラー、モノクロの順に載せる。前回記事では、文字列を結合して一行ずつ白キャンバスに貼り付けていたのだが、それでは字間が詰まるという問題があった。それゆえ、できあがるアスキーアートは横幅が半分に縮小されていた。今回、キャンバスをフォントサイズごとの区画に区切り、対応する文字を配置した。
  また、未だに画像に関係なくフォントサイズ24未満では文字がつぶれる問題がある。フォントに原因があるのか 何なのかわからない。
  RGBをそのままフォントに反映させることで着色したところ、白キャンパスに黄色の文字は明度が高くて見づらかった。
  フォントサイズを固定していると、元の画像のサイズによって埋め込める文字数が変わる。例えば、画像サイズが687x1024にフォントサイズ24を指定すると、687, 1024を24で割った商が28, 42であるため、28x42個の文字を埋め込めることになる。埋め込める文字数が少ないと、とても認識しづらい。




































ああああああ

コメント

人気の投稿