使用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中非常实用的一些功能和函数分享
Feb 14 Python
简单解析Django框架中的表单验证
Jul 17 Python
python3 爬取图片的实例代码
Nov 06 Python
Python基础之循环语句用法示例【for、while循环】
Mar 23 Python
python中报错"json.decoder.JSONDecodeError: Expecting value:"的解决
Apr 29 Python
python2.7的flask框架之引用js&css等静态文件的实现方法
Aug 22 Python
Python利用PyExecJS库执行JS函数的案例分析
Dec 18 Python
用Python绘制漫步图实例讲解
Feb 26 Python
Python图像处理库PIL的ImageFont模块使用介绍
Feb 26 Python
Centos7下源码安装Python3 及shell 脚本自动安装Python3的教程
Mar 07 Python
新手学习Python2和Python3中print不同的用法
Jun 09 Python
Python+Opencv实现把图片、视频互转的示例
Dec 17 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
Protoss兵种对照表
2020/03/14 星际争霸
第4章 数据处理-php正则表达式-郑阿奇(续)
2011/07/04 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
2015/01/28 PHP
Laravle eloquent 多对多模型关联实例详解
2017/11/22 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
js模拟类继承小例子
2010/07/17 Javascript
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
2011/05/07 Javascript
javascript中的注释使用与注意事项小结
2011/09/20 Javascript
js substr支持中文截取函数代码(中文是双字节)
2013/04/17 Javascript
用表格输出1-1000之间的数字实现代码(附特效)
2013/04/21 Javascript
学习JavaScript设计模式(继承)
2015/11/26 Javascript
AngularJS入门教程之AngularJS 模板
2016/08/18 Javascript
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
深入理解vue中的$set
2017/06/01 Javascript
JavaScript实现图片放大镜效果
2019/06/27 Javascript
jQuery实现数字华容道小游戏(实例代码)
2020/01/16 jQuery
vue移动端的左右滑动事件详解
2020/06/17 Javascript
微信小程序实现日历签到
2020/09/21 Javascript
微信小程序实现点击页面出现文字
2020/09/21 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
[01:52]PWL S2开团时刻第四期——DOTA2成语故事
2020/12/03 DOTA
Python下的twisted框架入门指引
2015/04/15 Python
python 远程统计文件代码分享
2015/05/14 Python
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
Python+Selenium自动化实现分页(pagination)处理
2017/03/31 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
将pip源更换到国内镜像的详细步骤
2019/04/07 Python
使用 css3 transform 属性来变换背景图的方法
2019/05/07 HTML / CSS
财务方面个人工作的自我评价
2013/12/28 职场文书
培训楼经理岗位责任制
2014/02/10 职场文书
《桃林那间小木屋》教学反思
2014/05/01 职场文书
感恩的演讲稿
2014/05/06 职场文书
2015年教育实习工作总结
2015/04/24 职场文书
住房公积金贷款工资证明
2015/06/12 职场文书
2016年中秋节慰问信
2015/12/01 职场文书
幼儿园语言教学反思
2016/02/23 职场文书