使用Python脚本将文字转换为图片的实例分享


Posted in Python onAugust 29, 2015

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

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

使用 PIL 将文字转换为图片

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

# -*- coding: utf-8 -*-
 
import os
import Image, ImageFont, ImageDraw
 
text = u"这是一段测试文本,test 123。"
 
im = Image.new("RGB", (300, 50), (255, 255, 255))
dr = ImageDraw.Draw(im)
font = ImageFont.truetype(os.path.join("fonts", "msyh.ttf"), 14)
 
dr.text((10, 5), text, font=font, fill="#000000")
 
im.show()
im.save("t.png")

生成的图片如下:

使用Python脚本将文字转换为图片的实例分享

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

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

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

效果如下:

使用Python脚本将文字转换为图片的实例分享

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

使用 pyGame 渲染点阵字体

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

代码如下:

# -*- coding: utf-8 -*-
 
import os
import pygame
 
pygame.init()
 
text = u"这是一段测试文本,test 123。"
font = pygame.font.Font(os.path.join("fonts", "simsun.ttc"), 14)
rtext = font.render(text, True, (0, 0, 0), (255, 255, 255))
 
pygame.image.save(rtext, "t.jpg")

效果如下:

使用Python脚本将文字转换为图片的实例分享

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

结合 PIL 和 pyGame

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

代码如下:

# -*- coding: utf-8 -*-
 
import os
import StringIO
import Image, ImageFont, ImageDraw
import pygame
 
pygame.init()
 
text = u"这是一段测试文本,test 123。"
 
im = Image.new("RGB", (300, 50), (255, 255, 255))
#dr = ImageDraw.Draw(im)
#font = ImageFont.truetype(os.path.join("fonts", "simsun.ttc"), 18)
font = pygame.font.Font(os.path.join("fonts", "simsun.ttc"), 14)
 
#dr.text((10, 5), text, font=font, fill="#000000")
rtext = font.render(text, True, (0, 0, 0), (255, 255, 255))
 
#pygame.image.save(rtext, "t.gif")
sio = StringIO.StringIO()
pygame.image.save(rtext, sio)
sio.seek(0)
 
line = Image.open(sio)
im.paste(line, (10, 5))
 
im.show()
im.save("t.png")

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

最终效果如下:

使用Python脚本将文字转换为图片的实例分享

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

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

使用Python脚本将文字转换为图片的实例分享

Python 相关文章推荐
python多线程操作实例
Nov 21 Python
CentOS 6.5下安装Python 3.5.2(与Python2并存)
Jun 05 Python
python 判断是否为正小数和正整数的实例
Jul 23 Python
Python 装饰器实现DRY(不重复代码)原则
Mar 05 Python
Python将文本去空格并保存到txt文件中的实例
Jul 24 Python
Python中 CSV格式清洗与转换的实例代码
Aug 29 Python
python多线程扫描端口(线程池)
Sep 04 Python
python中的TCP(传输控制协议)用法实例分析
Nov 15 Python
Spring http服务远程调用实现过程解析
Jun 11 Python
python实现视频压缩功能
Dec 18 Python
详解用Python把PDF转为Word方法总结
Apr 27 Python
教你用Python爬取英雄联盟皮肤原画
Jun 13 Python
Python中常见的数据类型小结
Aug 29 #Python
深入解析Python中的lambda表达式的用法
Aug 28 #Python
两个使用Python脚本操作文件的小示例分享
Aug 27 #Python
简介二分查找算法与相关的Python实现示例
Aug 26 #Python
使用Python的Bottle框架写一个简单的服务接口的示例
Aug 25 #Python
栈和队列数据结构的基本概念及其相关的Python实现
Aug 24 #Python
如何使用七牛Python SDK写一个同步脚本及使用教程
Aug 23 #Python
You might like
PHP文章采集URL补全函数(FormatUrl)
2012/08/02 PHP
PHP执行批量mysql语句的解决方法
2013/05/02 PHP
php文件上传的两种实现方法
2016/04/04 PHP
PHP7.1新功能之Nullable Type用法分析
2016/09/26 PHP
在Z-Blog中运行代码[html][/html](纯JS版)
2007/03/25 Javascript
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
在页面加载完成后通过jquery给多个span赋值
2014/05/21 Javascript
原生javascript实现图片按钮切换
2015/01/12 Javascript
DOM 高级编程
2015/05/06 Javascript
javascript验证手机号和实现星号(*)代替实例
2016/08/16 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
2017/01/13 Javascript
JavaScript中 DOM操作方法小结
2017/04/25 Javascript
bootstrap模态框远程示例代码分享
2017/05/22 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
解决npm管理员身份install时出现权限的问题
2018/03/16 Javascript
Vue.set()动态的新增与修改数据,触发视图更新的方法
2018/09/15 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
微信小程序实现发微博功能的示例代码
2020/06/24 Javascript
使用BeautifulSoup爬虫程序获取百度搜索结果的标题和url示例
2014/01/19 Python
python使用递归解决全排列数字示例
2014/02/11 Python
python实现爬虫下载漫画示例
2014/02/16 Python
Python制作词云的方法
2018/01/03 Python
python爬虫 2019中国好声音评论爬取过程解析
2019/08/26 Python
Python英文文章词频统计(14份剑桥真题词频统计)
2019/10/13 Python
解决Python二维数组赋值问题
2019/11/28 Python
CSS3教程(2):网页边框半径和网页圆角
2009/04/02 HTML / CSS
Roxy美国官网:澳大利亚冲浪、滑雪健身品牌
2016/07/30 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
大学生蛋糕店创业计划书
2014/01/13 职场文书
意向协议书范本
2014/04/23 职场文书
期末评语大全
2014/05/04 职场文书
2014年实验室工作总结
2014/12/03 职场文书
好员工观后感
2015/06/17 职场文书
会计入职心得体会
2016/01/22 职场文书
python Tkinter的简单入门教程
2021/04/11 Python