使用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中stdout输出不缓存的设置方法
May 29 Python
python同时给两个收件人发送邮件的方法
Apr 30 Python
python使用pymysql实现操作mysql
Sep 13 Python
linux平台使用Python制作BT种子并获取BT种子信息的方法
Jan 20 Python
用Pygal绘制直方图代码示例
Dec 07 Python
ubuntu安装sublime3并配置python3环境的方法
Mar 15 Python
python操作excel文件并输出txt文件的实例
Jul 10 Python
Python import与from import使用及区别介绍
Sep 06 Python
Python字典创建 遍历 添加等实用基础操作技巧
Sep 13 Python
python 3.6.2 安装配置方法图文教程
Sep 18 Python
Ubuntu+python将nii图像保存成png格式
Jul 18 Python
如何使用python自带IDLE的几种方法
Oct 10 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学习之PHP运算符
2006/10/09 PHP
PHP实现的简单日历类
2014/11/29 PHP
php身份证号码检查类实例
2015/06/18 PHP
jquery封装的对话框简单实现
2013/07/21 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
2014/05/08 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
JavaScript函数学习总结以及相关的编程习惯指南
2015/11/16 Javascript
基于jquery实现全屏滚动效果
2015/11/26 Javascript
简单的JS轮播图代码
2016/07/18 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
2016/10/09 Javascript
JSON对象 详解及实例代码
2016/10/18 Javascript
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
详解JavaScript的BUG和错误
2018/05/07 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
VueX模块的具体使用(小白教程)
2020/06/05 Javascript
JS中箭头函数与this的写法和理解
2021/01/14 Javascript
[13:18]《一刀刀一天》之DOTA全时刻21:详解TI新赛制 A队再露獠牙
2014/06/24 DOTA
python共享引用(多个变量引用)示例代码
2013/12/04 Python
Python中使用md5sum检查目录中相同文件代码分享
2015/02/02 Python
Python正则表达式完全指南
2017/05/25 Python
Python numpy生成矩阵、串联矩阵代码分享
2017/12/04 Python
Python多线程应用于自动化测试操作示例
2018/12/06 Python
pycharm设置鼠标悬停查看方法设置
2019/07/29 Python
Python+OpenCv制作证件图片生成器的操作方法
2019/08/21 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
html5 利用canvas实现超级玛丽简单动画
2013/09/06 HTML / CSS
移动端html5判断是否滚动到底部并且下拉加载
2019/11/19 HTML / CSS
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
应届大专生求职信
2014/06/26 职场文书
机关班子查摆问题及整改措施
2014/10/28 职场文书
2015法院个人工作总结范文
2015/05/25 职场文书
爱岗敬业事迹材料
2019/06/20 职场文书
七年级作文之雪景
2019/11/18 职场文书
win10如何开启ahci模式?win10开启ahci模式详细操作教程
2022/07/23 数码科技