Python实现图片转字符图

字符图是码农的浪漫。一个好的码农都想方设法的制作更加精良的字符图,所以直接上图:

原图

Python实现图片转字符图_第1张图片
彩色字符图


黑白图,filter=0


黑白图,filter=50

Python实现图片转字符图_第2张图片
参数说明

给大家介绍下这个脚本的参数:
–i : 输入图片。必选项。
–ratio : 图像的比例。默认比例为10,将图片尺寸压缩10倍,将每个像素 用一个字符进行替换,置为1则不进行压缩,相对的输出图像更加细腻,执行时间也比较长。
–muti_color: 控制输出图像是否为彩色。默认为1,设置为0后关闭彩色输出,字符图将为单色图。单色图采用的字符种类更多,用以区分不同颜色的密度情况。
–filter: 过滤值。当输出为单色图时,若图片环境复杂,彩图转换为单色图后,许多噪点将被特定字符映射,影响单色图质量;虽然单色图通过更多的字符区分不同的颜色信息,但仍无法过滤噪点影响。设置filter值能够将阈值低于设置值的点过滤,使图像中浅淡像素点不被映射,从而使图像更加清爽,减少噪点的影响。

源码

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont

import argparse

def getChar(pix, filter=0, mutiColor=True):
    if mutiColor:
        char = list("BEQDORAPMXFKHTYUVJZCLI")
    else:
        char = list("$$@@BB%%88&&WWMM##**oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+=<>i!1I;:,\"^`'....                    ")
    if type(pix) == type(int()):
        grey = pix
    else:
        r,g,b,a = pix if len(pix) == 4 else pix + (255,)
        grey = int((0.299*r + 0.587*g + 0.114*b)* (a/255.0))

    # Map
    return char[int(grey/255.0 * (len(char) - 1))] if grey >= filter else " "


def genMutiColorPix(image, filter=0, fontSize = 10, muti_color=True):
    width, height = image.size
    img = Image.new("RGB", (width*fontSize, height*fontSize), "white")
    draw = ImageDraw.Draw(img)
    ttfront = ImageFont.truetype('times.ttf', fontSize)
    #[[draw.ellipse((x * 1 * fontSize, y * 1 * fontSize, x * 1 * fontSize+8, y * 1 * fontSize+8), fill=im.getpixel((x,y))) for x in range(width)] for y in range(height)]
    #[[draw.rectangle((x * 1 * fontSize, y * 1 * fontSize, x * 1 * fontSize+ fontSize, y * 1 * fontSize+8 + fontSize), fill=im.getpixel((x,y))) for x in range(width)] for y in range(height)]
    [[draw.text((x * 1 * fontSize, y * 1 * fontSize), getChar(im.getpixel((x, y)), filter, muti_color), fill=im.getpixel((x,y)) if muti_color else "black", font=ttfront) for x in range(width)] for y in range(height)]
    img.save("bitmap.png")
    print("Done!")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--image", "-i", help = "Specify picture transferring to bitmap")
    parser.add_argument("--ratio", "--r", type=float, default=0, help="Specify resize ration")
    parser.add_argument("--filter", "--f", type=int, default=0, help = "Specify filter value")
    parser.add_argument("--muti_color", type = int, default=1, help = "To generate muti-color image")

    args = parser.parse_args()
    file = args.image
    ratio = args.ratio
    filter = args.filter
    mutiColor = args.muti_color
    im = Image.open(file)

    # Resize ratio
    width, height = im.size
    defaultRatio = 10
    if ratio == 0:
        im = im.resize((int((width//defaultRatio)), height//defaultRatio), Image.NEAREST)
    else:
        im = im.resize((int(width//ratio), int(height//ratio)), Image.NEAREST)
    width, height = im.size
    genMutiColorPix(im, filter, 10, mutiColor)

你可能感兴趣的:(字符图,Python)