使用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实现短网址ShortUrl的Hash运算实例讲解
Aug 10 Python
浅谈Python对内存的使用(深浅拷贝)
Jan 17 Python
Pandas 同元素多列去重的实例
Jul 03 Python
利用Python实现Shp格式向GeoJSON的转换方法
Jul 09 Python
python3 map函数和filter函数详解
Aug 26 Python
python时间日期操作方法实例小结
Feb 06 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
May 26 Python
详解python 内存优化
Aug 17 Python
详解python tkinter 图片插入问题
Sep 03 Python
K近邻法(KNN)相关知识总结以及如何用python实现
Jan 28 Python
Python基础知识学习之类的继承
May 31 Python
Python自动化爬取天眼查数据的实现
Jun 15 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
Yii学习总结之数据访问对象 (DAO)
2015/02/22 PHP
PHP中header用法小结
2016/05/23 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
2016/11/14 PHP
PHP常用算法和数据结构示例(必看篇)
2017/03/15 PHP
javascript中的prototype属性实例分析说明
2010/08/09 Javascript
js判断undefined类型,undefined,null, 的区别详细解析
2013/12/16 Javascript
jQuery中remove()方法用法实例
2014/12/25 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
2015/03/23 Javascript
js获取微信版本号的方法
2015/05/12 Javascript
JavaScript中toString()方法的使用详解
2015/06/05 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
JS全局变量和局部变量最新解析
2016/06/24 Javascript
jQuery实现的自定义弹出层效果实例详解
2016/09/04 Javascript
AngularJS使用Filter自定义过滤器控制ng-repeat去除重复功能示例
2018/04/21 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
Vue自定义指令上报Google Analytics事件统计的方法
2019/02/25 Javascript
JavaScript实现的联动菜单特效示例
2019/07/08 Javascript
详解vue 组件
2020/06/11 Javascript
使用Typescript开发微信小程序的步骤详解
2021/01/12 Javascript
解密Python中的描述符(descriptor)
2015/06/03 Python
详解Python中的array数组模块相关使用
2016/07/05 Python
Python利用matplotlib生成图片背景及图例透明的效果
2017/04/27 Python
Python可变和不可变、类的私有属性实例分析
2019/05/31 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
Python调用.NET库的方法步骤
2019/12/27 Python
手把手教你安装Windows版本的Tensorflow
2020/03/26 Python
Flask中sqlalchemy模块的实例用法
2020/08/02 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
详解python with 上下文管理器
2020/09/02 Python
Python中免验证跳转到内容页的实例代码
2020/10/23 Python
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
员工入职担保书范文
2014/04/01 职场文书
2015迎新晚会活动总结
2015/07/16 职场文书
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python