使用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实现3行代码解简单的一元一次方程
Aug 18 Python
python使用chardet判断字符串编码的方法
Mar 13 Python
将Python中的数据存储到系统本地的简单方法
Apr 11 Python
Python实现批量下载文件
May 17 Python
Python判断某个用户对某个文件的权限
Oct 13 Python
python使用Tkinter实现在线音乐播放器
Jan 30 Python
python基础教程项目三之万能的XML
Apr 02 Python
Python3实现爬取指定百度贴吧页面并保存页面数据生成本地文档的方法
Apr 22 Python
python协程之动态添加任务的方法
Feb 19 Python
python3实现二叉树的遍历与递归算法解析(小结)
Jul 03 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
python实现图片转字符画
Feb 19 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截取中文字符串不乱码的方法
2013/12/25 PHP
详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
2015/07/31 PHP
PHP实现二维数组按某列进行排序的方法
2016/11/18 PHP
一次因composer错误使用引发的问题与解决
2019/03/06 PHP
js 数组实现一个类似ruby的迭代器
2009/10/27 Javascript
JQUERY设置IFRAME的SRC值的代码
2010/11/30 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
javascript弹出页面回传值的方法
2015/01/28 Javascript
javascript实现在网页任意处点左键弹出隐藏菜单的方法
2015/05/13 Javascript
javascript禁止访客复制网页内容的实现代码
2015/08/05 Javascript
JavaScript DOM节点操作方法总结
2016/08/23 Javascript
深入解析js轮播插件核心代码的实现过程
2017/04/14 Javascript
js将键值对字符串转为json字符串的方法
2018/03/30 Javascript
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
vue打包相关细节整理(小结)
2018/09/28 Javascript
js实现下拉框二级联动
2018/12/04 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
Python判断操作系统类型代码分享
2014/11/22 Python
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
python利用rsa库做公钥解密的方法教程
2017/12/10 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
Python生成一个迭代器的实操方法
2019/06/18 Python
使用css3和jquery实现可伸缩搜索框
2014/02/12 HTML / CSS
深入浅析CSS3中的Flex布局整理
2020/04/27 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
HTML5地理定位实例
2014/10/15 HTML / CSS
美国汽车交易网站:Edmunds
2016/08/17 全球购物
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
大专自我鉴定范文
2013/10/23 职场文书
法人代表授权委托书范文
2014/09/10 职场文书
运动会广播稿诗歌版
2014/09/12 职场文书
2015领导干部廉洁自律工作总结
2015/07/23 职场文书
2016春季小学开学寄语
2015/12/03 职场文书
读《钢铁是怎样炼成的》有感:百炼方成钢
2019/11/05 职场文书
golang 实现两个结构体复制字段
2021/04/28 Golang
PyTorch dropout设置训练和测试模式的实现
2021/05/27 Python