python的闭包和装饰器
coursera课程字幕批量下载

用 PIL 制作 ASCII Art

scturtle posted @ 2012年2月26日 13:22 in python , 1998 阅读

把每一个字符绘制到一个小的区域中, 然后计算整个区域中的灰白比例, 得到对应的一个参数, 按参数排列得到一个字符按疏密排序后的列表.

import Image, ImageDraw, ImageFont
from itertools import product

def get_data_list():
    fontpath = '/usr/share/fonts/TTF/DejaVuSansMono.ttf'
    fontsize = 20
    h = 24
    w = int(h*0.618)
    charlist = r'''0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~!@#$%^&*()-_=+[{]}\|;:'",<.>/?'''

    def get_char_data(c):
        im = Image.new('L',(w, h),255)
        draw = ImageDraw.Draw(im)
        font = ImageFont.truetype(fontpath, fontsize)
        draw.text((0,0), c, font = font)
        #im.show()
        ans = 0.0
        for i, j in product(range(w), range(h)):
            ans += im.getpixel((i,j))
        return ans / (255.0 * w * h)

    lst = map(lambda c: [c, get_char_data(c)], charlist)
    lst.sort(key=lambda i: i[1])

    return lst


然后把要转换的图片转成灰度, 因为每个字符的宽长比大约是1/2, 所以图片的宽度要先伸展2倍, 然后缩小的一个需要的大小, 用每个像素的灰度值索引到之前算出的列表中的相应字符, 输出即可.

import Image
from pre import get_data_list
from itertools import product

clst = get_data_list()

im = Image.open('stevejobs.png')
size = list(im.size)
size[0]=size[0]/0.5
width = 70
size = (width,int(size[1]/size[0]*width))
im = im.resize(size)
im = im.convert('L')
#im.show()

fo = file('asciiart.txt','w')
for j in range(size[1]):
    for i in range(size[0]):
        idx = int( im.getpixel((i,j)) / 255.0 * (len(clst)-1) )
        fo.write(clst[idx][0])
    fo.write('\n')
fo.close()

效果图:

离远点看, 还是有点意思的~


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter