使用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编程实现语音控制电脑
Apr 01 Python
python定时检查某个进程是否已经关闭的方法
May 20 Python
Python实现SVN的目录周期性备份实例
Jul 17 Python
Mac中Python 3环境下安装scrapy的方法教程
Oct 26 Python
使用python生成目录树
Mar 29 Python
Python将图片转换为字符画的方法
Jun 16 Python
Sanic框架流式传输操作示例
Jul 18 Python
Python实现查找数组中任意第k大的数字算法示例
Jan 23 Python
Python使用线程来接收串口数据的示例
Jul 02 Python
浅谈在django中使用redirect重定向数据传输的问题
Mar 13 Python
使用Djongo模块在Django中使用MongoDB数据库
Jun 20 Python
Python干货实战之八音符酱小游戏全过程详解
Oct 24 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 screw加密php源代码
2013/06/20 PHP
解析php取整的几种方式
2013/06/25 PHP
PHP中构造函数和析构函数解析
2014/10/10 PHP
PHP7常量数组用法分析
2016/09/26 PHP
JavaScript 和 Java 的区别浅析
2013/07/31 Javascript
JS获得浏览器版本和操作系统版本的例子
2014/05/13 Javascript
IE6中链接A的href为javascript协议时不在当前页面跳转
2014/06/05 Javascript
js实现非常简单的焦点图切换特效实例
2015/05/07 Javascript
jquery中cookie用法实例详解(获取,存储,删除等)
2016/01/04 Javascript
值得分享的轻量级Bootstrap Table表格插件
2016/05/30 Javascript
AngularJS中watch监听用法分析
2016/11/04 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
傻瓜式解读koa中间件处理模块koa-compose的使用
2018/10/30 Javascript
详解element-ui中表单验证的三种方式
2019/09/18 Javascript
[01:32]DOTA2上海特锦赛现场采访:最想COS的英雄
2016/03/25 DOTA
Python实现保证只能运行一个脚本实例
2015/06/24 Python
Python用threading实现多线程详解
2017/02/03 Python
Python2实现的图片文本识别功能详解
2018/07/11 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
python实现对象列表根据某个属性排序的方法详解
2019/06/11 Python
浅谈django channels 路由误导
2020/05/28 Python
python脚本定时发送邮件
2020/12/22 Python
css3的transition属性详解
2014/12/15 HTML / CSS
查摆问题整改措施
2014/10/24 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书
公司财务经理岗位职责
2015/04/08 职场文书
药品销售内勤岗位职责
2015/04/13 职场文书
少先队中队工作总结2015
2015/07/23 职场文书
婚宴致辞
2015/07/28 职场文书
2016国培学习心得体会
2016/01/08 职场文书
《巨人的花园》教学反思
2016/02/19 职场文书
你知道哪几种MYSQL的连接查询
2021/06/03 MySQL
详解如何使用Nginx解决跨域问题
2022/05/06 Servers