好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

python入门,字符画和图片写字

前言

最近看完了python的基础语法,该怎么继续呢?还是继续在网上找课程,学习吧,也计划看看有没有可以利用在工作上的内容。

近一周多搞了两个内容,都是利用python处理图片,一个是在图片上的最左上角输入字符,一个是用python生成字符画,这里呢因为都用到了pillow库所以放在一起记录一下。

pillow库简单介绍

是一个图像处理的库。自己参考了这两篇内容: https://zhuanlan.zhihu.com/p/59849190 https://zhuanlan.zhihu.com/p/58671158

1、python图片上添加文字

这里要求的是 图片的左上角放置一段文字 。 首先需要导入库的几个类

 from PIL import Image,ImageDraw,ImageFont 

接下来我们要用python读取图片来进行后续的操作

 image1 = Image.open(path)  #path是图片路径,windows的话写成类似'C:\\Users\\ytds\\Desktop\\MYTEST\\ca.jpg' 

要在图片上进行绘制,需要再根据Image对象创建ImageDraw对象。

 draw = ImageDraw.Draw(image1) 

现在我们就可以调用draw的不同方法在我们读取的图片上绘画了,具体介绍看上边的第一个链接。

这里我们要做的是写字,所以用到的方法是:draw.text()。这里我总结一下自己使用时的点:

如果不设置字体参数,则不能调整图片上的字大小(我没有找到调整的方法,我只会通过字体参数来调整字的大小)

因为上边提到了要设字体参数,那么我们需要指定一个字体,这里可以调整它的大小。

 font = ImageFont.truetype('C:\\Users\\ytds\\Desktop\\MYTEST\\calibri.ttf',size=num) 

有了字体我们就可以往图片上写字了。

 draw.text((x,y),text,font=font,fill='#DC143C') #(x,y)是第一个字的位置 

至此,我们基本就实现了我们的想法。但是还有几个问题

如何判断一段文字能被放入图片中(这里牵扯到是否换行,我是选择不换行) 如何确保一段文字刚好在最左边?

要解决以上问题,我们需要知道图片的大小和文字的大小,可以通过以下方法获得

 image1.width #获取图片的宽
image1.height #获取图片的高
move = draw.textsize(text,font) #获取绘制文字的大小,返回一个元组(width,height) 

这样通过一些判断就可以解决问题了。剩下的就是把我们操作后的东西保存成图片了。

 image1.save(path) 

2、python绘制字符画

这是一个根据一个教程走完的,这里推荐一个地址:https://www.bilibili.com/read/cv1859294/ 里面介绍了字符画的实现原理,通过这个可以了解关键函数的基本原理。

2.1 代码目标

读取一副图片,用字符给出模拟图。命令行接收参数,参数写法类似于操作系统命令。

pyton3 pic.py filename -o filename --height xxx

2.2 接受参数的部分实现

首先继续是一个参考网址:https://docs.python.org/zh-cn/3/howto/argparse.html#argparse-tutorial 可以深入了解需要的内容或是丰富选项。

我们的代码就接受一个图片,给出一个存放字符内容的文件,以及可以设置字符画的宽和高,宽和高默认的值为300。设置代码如下:

 import argparse #导入模块

#命令行输入参数处理
parser = argparse.ArgumentParser()
## 以下是添加了从命令行可以接受的参数名称,以及参数的类型和默认值
parser.add_argument('file')     #位置参数,必须有,输入文件
parser.add_argument('-o', '--output')   #可选参数 输出文件
parser.add_argument('--width', type = int, default = 80) #可选参数,默认类型为字符,这里指定成数字 输出字符画宽
parser.add_argument('--height', type = int, default = 80) # 输出字符画高

#获取参数
args = parser.parse_args() 

这样我们给出的参数就保存在args中了,用args.来使用参数。

 IMG = args.file
WIDTH = args.width
HEIGHT = args.height
OUTPUT = args.output 
2.2 图片转换部分

简单说下思路:图片的彩色值变为灰度值,灰度值对应成字符串中的字符,灰度值有256个,字符串中的字符一般没有那么多,所以要把一个字符对应多个灰度值。

这里我曾有疑问就是字符串的选择是随意的吗?看过开头链接的介绍后我知道了

字符串可以是任意的,都能显示出图片的轮廓,但是如果要像的话,那么最好字符串开始的字符大而满,后边的字符少而小,符合灰度的递减。

下边是教程转换代码:

 ### 实现图片转换的函数
def get_char(r,g,b,alpha = 256):  #参数为图片的 rgba值,前三个比较好理解,最后一个在png图时,没内容的地方值为0
    if alpha == 0:     # 判断,如果没内容返回空格
        return ' '
    length = len(ascii_char)
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b) #彩色转灰度

    unit = (256.0 + 1)/length
    return ascii_char[int(gray/unit)]  # 灰度转成字符串的index 

至此,我们能把一个个的灰度转换成字符了,后续我们只要直接获取图片的所有灰度值,并打印出字符即可了。

 from PIL import Image

im = Image.open(IMG) #打开图片
im = im.resize((WIDTH,HEIGHT), Image.NEAREST) #调整图片大小

txt = ""

for i in range(HEIGHT):
    for j in range(WIDTH):
        txt += get_char(*im.getpixel((j,i))) #获取的值传给get_char()函数,值是一个元组
    txt += '\n'  #换行

print(txt) 

上边用到了一个我之前不知道的内容

 In [1]: a = (1,2,3,4)  

In [2]: b,c,d,e= *a  
File "<ipython-input-2-3f4b061fea3e>", line 4  
SyntaxError: can't use starred expression here  

In [3]: *a  
File "<ipython-input-3-b252d56222c4>", line 4  
SyntaxError: can't use starred expression here  

In [4]: print(*a)  
1 2 3 4  

In [5]: def test(b,c,d,e):  
   ...:     return b+c+d+e...:  

In [6]: test(*a)  #当参数带*
Out[6]: 10  

In [7]: b,c,d,e= a  #不用*,可直接拆开

In [8]: b  
Out[8]: 1 

就是知道一下元组可以这样用,至于原因先不查了。

3 结尾

回过头再看一遍,其实难的地方不多,大部分是知道了就可以用的知识。当然了,熟练度还是很重要的。

现就这样慢慢的熟悉一下python,再继续往后走吧。

查看更多关于python入门,字符画和图片写字的详细内容...

  阅读:28次