将图片转换成字符画

将图片的每个像素用一个字符替换,就可以有一副图片的字符画。

  • 创建图片的缩略图
  • 获取图片的像素点数据
  • 使用字符绘制像素点

完整代码

from PIL import Image, ImageDraw, ImageFont
import os

symbols = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")


def load_picture(filename):
    # Gray = R*0.299 + G*0.587 + B*0.114
    img = Image.open(filename).convert('L')
    (x, y) = img.size

    pixels = list(img.getdata())
    img.close()
    return (pixels, x, y)


def create_thumbnail(src_dir, dst_dir):
    img = Image.open(src_dir)
    size = 200, 200
    img.thumbnail(size, Image.ANTIALIAS)
    img.save(dst_dir)


def create_ascii_picture(pixels, symbols, dest_name, x_size, y_size):
    scale = 4  # 长宽扩大倍数
    border = 1  # 边框宽度

    interval_pixel = 2  # 原图片间隔多少个像素点来填充

    img = Image.new('L',
                    (x_size * scale + 2 * border,
                     y_size * scale + 2 * border),
                    255)
    fnt = ImageFont.truetype('Raleway-ExtraLight.ttf', int(scale * 3))
    t = ImageDraw.Draw(img)

    x = border
    y = border
    for j in range(0, y_size, interval_pixel):
        for i in range(0, x_size, interval_pixel):
            t.text((x, y),
                   symbols[int(pixels[j * x_size + i] / 256 * len(symbols))],
                   font=fnt,
                   fill=0
                   )
            x += scale * interval_pixel
        x = border
        y += scale * interval_pixel

    img.save(dest_name, "JPEG")


if __name__ == '__main__':
    fileName = 'girl_friend.jpeg'
    fileNameThub = 'girl_friend_thub.jpeg'
    create_thumbnail(fileName, fileNameThub)
    pix, x, y = load_picture(fileNameThub)
    destFileName = 'girl_friend_1.jpeg'
    create_ascii_picture(pix, symbols, destFileName, x, y)

这里用到了一个字体文件Raleway-ExtraLight.ttf,可以去网站上下载一个好看的字体。

你可能感兴趣的:(将图片转换成字符画)