使用Python将文本转为图片

本文介绍了如何使用Python将文本转换为图片,探讨了使用PIL库遇到的点阵字体问题,并通过引入pyGame解决。通过结合两者,实现了包括点阵字体在内的文本转图片功能,同时提到了实际应用中要考虑的长文本换行等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时候,我们需要将文本转换为图片,比如发长微博,或者不想让人轻易复制我们的文本内容等时候。目前类似的工具已经有了不少,不过我觉得用得都不是很趁手,于是便自己尝试实现了一个。你可以先访问一下查看效果:txt2.im 。

  txt2.im

  在 Python 中,PIL (Python Imaging Library) 是最常用的绘图库,自然地,尝试从 PIL 开始。

  1、使用 PIL 将文字转换为图片

  说转换其实并不恰当,真实的过程是:先在内存中生成一张图片,将需要的文字绘制到这个图片上,再将图片保存到指定位置。代码如下:

01 # -*- coding: utf-8 -*-
02  
03 import os
04 import Image, ImageFont, ImageDraw
05  
06 text = u"这是一段测试文本,test 123。"
07  
08 im = Image.new("RGB", (30050), (255255255))
09 dr = ImageDraw.Draw(im)
10 font = ImageFont.truetype(os.path.join("fonts""msyh.ttf"), 14)
11  
12 dr.text((105), text, font=font, fill="#000000")
13  
14 im.show()
15 im.save("t.png")

  当然,要使上面的代码能正常运行,你还需要在代码目录建一个“fonts”文件夹,并将字体文件“msyh.ttf”(微软雅黑)放在里面。最终生成的图片效果如下:

  

  从上面可以看到,使用 PIL 把文本转为图片是非常方便的。当然,上面还只是一个简单的例子,还没有考虑长文本换行的问题。

  2、使用点阵字体

  对于大多数屏幕阅读来说,较小的字号(<= 14px)使用点阵字体来说更加清晰和便于阅读,例如 Windows 中文版下的默认字体宋体在字号较小时就通常被渲染成点阵字体。那么,我们是否可以在生成的图片中使用点阵字体呢?

  修改上面的代码的第 10 行,将字体从微软雅黑(msyh.ttf)换成了宋体(simsun.ttc),其它保持不变。

1 font = ImageFont.truetype(os.path.join("fonts""simsun.ttc"), 14)

  生成的图片如下:

  

  杯具发生了,汉字没有正常显示!

  网上搜索了一圈,发现这好像是 PIL 的一个 bug,PIL 目前的版本中,不能正确处理非 ASCII 字符的点阵字体的渲染。对于像宋体这样的字体来说,只有 >= 18px 时,才会被当作矢量字体处理,也就是说只有当字体 >= 18px 时,文字才能正常显示:

1 font = ImageFont.truetype(os.path.join("fonts""simsun.ttc"), 18)

  效果如下:

  

  增大字体虽然解决了汉字不能正常显示的问题,但还是没有解决我们一开始的初衷:使用点阵字体进行渲染。但是,这个目标使用现阶段的 PIL 似乎有点难以实现了。

  3、使用 pyGame 渲染点阵字体

  Python 的第三方模块或组件非常多,可用来绘图的除了 PIL 之外,就还有 PycairomatplotlibpyGame 等。在这儿,我使用 pyGame 来完成点阵字体的渲染工作。

  代码如下:

01 # -*- coding: utf-8 -*-
02  
03 import os
04 import pygame
05  
06 pygame.init()
07  
08 text = u"这是一段测试文本,test 123。"
09 font = pygame.font.Font(os.path.join("fonts""simsun.ttc"), 14)
10 rtext = font.render(text, True, (000), (255255255))
11  
12 pygame.image.save(rtext, "t.jpg")

  效果如下:

  

  可以看到,使用 pyGame ,点阵字体的问题终于搞定了。

  4、结合 PIL 和 pyGame

  pyGame 虽然可以解决点阵字体的渲染问题,但讲到对图片的处理,还是 PIL 更为强大。那么,我们为什么不把两者结合起来呢?用 pyGame 渲染点阵字体,然后用 PIL 生成整张图片。

  代码如下:

01 # -*- coding: utf-8 -*-
02  
03 import os
04 import StringIO
05 import Image, ImageFont, ImageDraw
06 import pygame
07  
08 pygame.init()
09  
10 text = u"这是一段测试文本,test 123。"
11  
12 im = Image.new("RGB", (30050), (255255255))
13 #dr = ImageDraw.Draw(im)
14 #font = ImageFont.truetype(os.path.join("fonts", "simsun.ttc"), 18)
15 font = pygame.font.Font(os.path.join("fonts""simsun.ttc"), 14)
16  
17 #dr.text((10, 5), text, font=font, fill="#000000")
18 rtext = font.render(text, True, (000), (255255255))
19  
20 #pygame.image.save(rtext, "t.gif")
21 sio = StringIO.StringIO()
22 pygame.image.save(rtext, sio)
23 sio.seek(0)
24  
25 line = Image.open(sio)
26 im.paste(line, (105))
27  
28 im.show()
29 im.save("t.png")

  原理很简单,先将文字用 pyGame 渲染为图片,将渲染结果保存在一个 StringIO 对象中,然后再用 PIL 加载它。使用 StringIO 的好处是,一切操作都是在内存中进行的,不需要先将它保存到硬盘再用 PIL 读取,因为硬盘 IO 的效率相对来说是比较低的。

  最终效果如下:

  

  

  到这儿,使用 Python 将文本转为图片的功能就基本实现了,用到了 PIL 和 pyGame。

  当然,上面的代码还只解决了最基本的问题,一个真正可用的文本转图片工具,还应该解决以下问题:长文本换行问题、英文单词断字问题、标点符号换行问题等。关于这些问题的分析篇幅也不短,这一次就先略过了。下面是一个综合考虑了诸多因素之后生成的《荷塘月色》的效果图:

  

  最后,欢迎试用我写的在线文本转图片工具:txt2.im 。:-)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值