Python实战1- 图片转字符画

Python实战系列用于记录实战项目中的思路,代码实现,出现的问题与解决方案
本文为第1篇–图片转字符画
参考教程:https://www.cnblogs.com/MartinLwx/p/9143844.html

一、步骤

分析:字符画原理是将图片的灰度值与个人设定的字符集之间建立映射关系,不同区间的灰度值对应不同的字符,之后将图片每一个像素对应的字符打印出来,即可获得字符画

  1. 将原图片转化为灰度图片
    方案一:利用灰度公式将像素的 RGB 值映射到灰度值
    gray = 0.2126 * r + 0.7152 * g + 0.0722 * b
    方案二:利用PIL库所带的convert(“L”)函数转化图片

  2. 将图片的灰度值与个人设定的字符集之间建立映射关系
    可以自己设定,也可以找网上教程里给出的,下面将给出两种参考方案
    方案一:

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

    方案二:

    ascii_char = list("qwertyuiop[]asdfghjkl;'zxcvbnm,./`~!@#$%^&<()*+{}:"?> |")
    

    经测试,方案二生成的图片真实度更高

  3. 将字符串保存到txt文件

二、代码实现

注:IDE为Spyder,Python版本为3.6,推荐使用Anaconda,自带Pillow库。否则要提前安装好pillow。
pillow库安装教程:

  1. 用管理员身份打开命令提示符
  2. 输入pip install pillow

代码实现如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Sep 28 23:23:44 2018

@author: PastoralDog
"""
from PIL import Image

class ASCIIart(object):
    def __init__(self,file):
        self.file=file
        self.codelist = """qwertyuiop[]asdfghjkl;'zxcvbnm,./`~!@#$%^&<()*+{}:"?> |"""
        self.img=Image.open(file)
        self.count=len(self.codelist)
        
    def to_ASCII(self):
        img = self.img.convert("L")
        asciilist = ''
        for h in range(0,img.size[1]):
            for w in range(0,img.size[0]):
                gray = img.getpixel((w,h))
                pos = gray/256
                #asciilist = asciilist + self.codelist[int((self.count-1)*pos)]
                asciilist = asciilist + self.codelist[int((self.count-1)*pos)]+" "+self.codelist[int((self.count-1)*pos)]
            asciilist = asciilist+"\n"
        return asciilist
    
    def to_txt(self):
        outfile = open('ASCIIart.txt', 'w')
        outfile.write(self.to_ASCII())
        outfile.close()
        
    def _resize(self,rate):
        width = self.img.size[0]
        height = self.img.size[1]
        scale = width / height
        self.img = self.img.resize((int(width*rate), int(width*rate/scale) ))
                
if __name__ == '__main__':
    file="test.jpg"
    img=ASCIIart(file)
    img.to_txt()

三、出现的问题及解决方案

  1. 图像失真严重
    采用方案一的编码生成的字符画效果不是很好,改用方案二后得到解决

  2. 图像左右过于窄
    我们以下图为例
    原图
    代码1

    代码2
    第二张核心代码:

    asciilist = asciilist + self.codelist[int((self.count-1)*pos)]
    

    第三张核心代码:

    asciilist = asciilist + self.codelist[int((self.count-1)*pos)]+" "+self.codelist[int((self.count-1)*pos)]
    

    由于第二张过窄,我们就加点东西(" "+self.codelist[int((self.count-1)*pos))使它丰满起来

本人水平有限,欢迎大家提出问题与建议。若代码有看不懂的地方,也欢迎提出!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值