Python简单实现图片转字符画的实例项目

 更新时间:2021年04月21日 10:49:47   作者:David 612  
这篇文章主要介绍了Python简单实现图片转字符画的实例项目,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

1. 原理

利用 PIL 库来获取图片并修改大小,
利用灰度值转换公式把每一个像素的 RGB 值转为灰度值

gray = int(0.2126*r+0.7152*g+0.0722*b)

再从字符集里获取对应的字符

asciis = list('M%$@#&WNBRwm8S5A4E3KXFPH69nsxeazgpqbdoctfhkyvuGZYVTUCI2QOD0L7Jjl1ri!^{}[]()/|;:*<>_~-,. ')

最后将字符连接起来并保存就完成了

2. 开始制作

2.1 导入所需的库

在这个工程中,我们需要的第三方库是 PIL
但我们不用 pip install PIL 来安装它,而是使用 pip install pillow

pip install pillow

导入库
在导入 PIL 库时,不能用 import pillow,应使用 import PIL

from PIL import Image as Image

2.2 获取图片路径和选项

inputfile = input('inputfile:')
outputfile = input('outputfile:')
distance = {'y':' ','':' ','n':''}
distance = distance[input('distance?(Y/n):')]
re = input("resize?:")

字母占用的位置是矩形的,因此生成出来的字符画会被“挤压”。我们可以在字母与字母之间添加空格来防止这种情况的发生。
如果图片太大了,会导致耗费时间过长、乱码等问题。我们应该对图片进行必要的缩放。在询问“resize?”时,可以设置以下几种回答:

回答方式 作用
“”,啥也不输入 不缩放
“100”,边长 输入单个数字时,会按比例缩放为较长边为此长度的矩形
“100,200”,宽和高 缩放为指定宽高的矩形

2.3 图片获取

使用 PILopen 函数打开图片

image = Image.open(inputfile)

注意:这里的 open 函数不要和 python 内置函数 open 混淆

2.4 调整图片大小

获取图片大小

w, h = image.size

获取变量 re 中存储的大小信息,并用函数 split 分割

nwh = re.split(',')
for i in range(len(nwh)):
    nwh[i] = int(nwh[i])

调整图片大小

if len(nwh) == 1:
    #如果项数为1,表示用户只输入了一个数字。即按比例缩放为较长边为此长度的矩形
    ww = int(nwh[0] / max(w,h) * w) #max函数获取较大值
    hh = int(nwh[0] / max(w,h) * h)
    image = image.resize((ww,hh),Image.ANTIALIAS) 
    #改变图片大小
    #第一个参数放入一个元组,指定宽高
    #第二个参数 Image.ANTIALIAS 表示获取高质量图片
else:
    #项数不为1,缩放为指定宽高的矩形
    image = image.resize((nwh[0],nwh[1]),Image.ANTIALIAS)

2.5 转换字符

指定转换的字符集

asciis = list('M%$@#&WNBRwm8S5A4E3KXFPH69nsxeazgpqbdoctfhkyvuGZYVTUCI2QOD0L7Jjl1ri!^{}[]()/|;:*<>_~-,. ')
#list函数将字符串转换为列表

定义转换字符的函数

def getasc(r,g,b,t=100): #t为透明度
    if t == 0:
        return(' ') #如果是透明的,则直接返回空值
    else:
        asc = ''
        gray = int(0.2126*r+0.7152*g+0.0722*b) #转灰度值
        asc = asciis[int(len(asciis)/256*(gray))] #获取字符
        return(asc)

开始转换字符

for i in range(h):
    for o in range(w): #按行读取每一个像素的RGB值
        p = image.getpixel((o,i))
        g = getasc(*p) # * 将参数列表转换为多个项
        txt = txt + g + distance #连接字符
    txt = txt + '\n' #换行

函数 getpixel 获取指定位置的 RGB 值,它的第一个参数为元组,传入像素位置 (x,y),如果图片是 JPG 格式的,它会返回含三项的列表 [r,g,b],如果图片是 PNG 格式的,它会返回含四项的列表 [r,g,b,t]t 是透明度

2.6 保存文本

使用 python 内置函数 open 保存文件

with open(outputfile,'w') as f: # 'w' 表示写入
    f.write(txt)

2.7 效果

================== RESTART: D:\Python38-32\Files\ji2a\ji2a.py ==================
=====image to ascii=====
inputfile:
dora.png
outputfile:
dora.txt
distance?(Y/n):
y
resize?(needn't:'', square:side length, restangle:width,height):
100

Opening 'dora.png'...
Getting...
Saving...
Seccessfully

原图:

原图

结果:

结果

3. 完整代码

from PIL import Image as Image
  
asciis = list('M%$@#&WNBRwm8S5A4E3KXFPH69nsxeazgpqbdoctfhkyvuGZYVTUCI2QOD0L7Jjl1ri!^{}[]()/|;:*<>_~-,. ')
#gray = int(0.2126*r+0.7152*g+0.0722*b)

def main():
    global asciis

    print('=====image to ascii=====')
    
    inputfile, outputfile, distance, re = getargs()

    image = openfile(inputfile)

    image = resize(image,re)
    w, h = image.size

    txt = gettxt(image,w,h,distance)

    savefile(outputfile,txt)

    print('Seccessfully')

def getargs():
    inputfile = input('inputfile:\n')
    outputfile = input('outputfile:\n')
    distance = {'':' ','y':' ','n':''}
    distance = distance[input('distance?(Y/n):\n')]
    re = input("resize?(needn't:'', square:side length, restangle:width,height):\n")

    return(inputfile,outputfile,distance,re)

def openfile(inputfile):
    print("\nOpening '"+inputfile+"'...")
    image = Image.open(inputfile)

    return(image)

def resize(image,re):
    if re != '':
        print('Resizing...')
        nwh = re.split(',')
        for i in range(len(nwh)):nwh[i]=int(nwh[i])
        w, h = image.size
        
        if len(nwh) == 1:
            ww = int(nwh[0] / max(w,h) * w)
            hh = int(nwh[0] / max(w,h) * h)
            image = image.resize((ww,hh),Image.ANTIALIAS)
        else:
            image = image.resize((nwh[0],nwh[1]),Image.ANTIALIAS)
        
    return(image)

def gettxt(image,w,h,distance):    
    txt = ''
    print('Getting...')

    for i in range(h):
        for o in range(w):
            p = image.getpixel((o,i))
            txt = txt + getasc(*p) + distance
        txt = txt + '\n'

    return(txt)
    
    
def getasc(r,g,b,t=100):
    if t == 0:
        return(' ')
    else:
        asc = ''
        gray = int(0.2126*r+0.7152*g+0.0722*b)
        asc = asciis[int(len(asciis)/256*(gray))]
        return(asc)

def savefile(outputfile,txt):
    print('Saving...')
    
    with open(outputfile,'w') as f:
        f.write(txt)

    return()

if __name__ == '__main__':
    main()

此代码在 Python3.8 下调试通过

4. 后记

我们的图片转字符画程序完成了!

要想将它打造成一个真正的命令行工具,可以加入命令行参数功能,
利用 sys 模块的 argv 函数获取命令行参数,
利用 getopt 模块的 getop 函数解析命令行参数。

到此这篇关于Python简单实现图片转字符画的实例项目的文章就介绍到这了,更多相关Python 图片转字符画内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在 Pycharm 安装使用black的方法详解

    在 Pycharm 安装使用black的方法详解

    这篇文章主要介绍了如何在 Pycharm 安装使用black的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • python获取文件扩展名的方法

    python获取文件扩展名的方法

    这篇文章主要介绍了python获取文件扩展名的方法,涉及Python针对文件路径的相关操作技巧,非常简单实用,需要的朋友可以参考下
    2015-07-07
  • python 实现在Excel末尾增加新行

    python 实现在Excel末尾增加新行

    下面小编就为大家分享一篇python 实现在Excel末尾增加新行,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python GUI自动化实现绕过验证码登录

    Python GUI自动化实现绕过验证码登录

    这篇文章主要介绍了python GUI自动化实现绕过验证码登录,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Python将string转换到float的实例方法

    Python将string转换到float的实例方法

    在本篇文章中小编给大家分享的是关于Python将string转换到float的实例方法以及相关知识点,需要的朋友们参考下。
    2019-07-07
  • asyncio异步编程之Task对象详解

    asyncio异步编程之Task对象详解

    这篇文章主要为大家详细介绍了asyncio异步编程之Task对象,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • django如何计算两个TimeField的时差

    django如何计算两个TimeField的时差

    在Django中,可以使用datetime模块来计算两个TimeField字段的时间差,下面通过示例代码介绍django 计算两个TimeField的时差,需要的朋友可以参考下
    2023-05-05
  • Jupyter Notebook远程登录及密码设置操作

    Jupyter Notebook远程登录及密码设置操作

    今天小编就为大家分享一篇Jupyter Notebook远程登录及密码设置操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • Python随机生成均匀分布在三角形内或者任意多边形内的点

    Python随机生成均匀分布在三角形内或者任意多边形内的点

    这篇文章主要为大家详细介绍了Python随机生成均匀分布在三角形内或者任意多边形内的点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • pandas dataframe中双中括号和单中括号的区别及说明

    pandas dataframe中双中括号和单中括号的区别及说明

    这篇文章主要介绍了pandas dataframe中双中括号和单中括号的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论