使用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 mysqldb连接数据库
Mar 16 Python
在Docker上开始部署Python应用的教程
Apr 17 Python
Python的Django框架中的数据库配置指南
Jul 17 Python
详解 Python 与文件对象共事的实例
Sep 11 Python
python将文本中的空格替换为换行的方法
Mar 19 Python
python中使用zip函数出现错误的原因
Sep 28 Python
详解Python requests 超时和重试的方法
Dec 18 Python
Python3 合并二叉树的实现
Sep 30 Python
python ctypes库2_指定参数类型和返回类型详解
Nov 19 Python
使用Pytorch来拟合函数方式
Jan 14 Python
Python线程条件变量Condition原理解析
Jan 20 Python
python3中的logging记录日志实现过程及封装成类的操作
May 12 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
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
extjs 学习笔记(一) 一些基础知识
2009/10/13 Javascript
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
Javascript的getYear、getFullYear、getUTCFullYear异同分享
2011/11/30 Javascript
JSON.stringify 语法实例讲解
2012/03/14 Javascript
js 窗口抖动示例
2013/09/04 Javascript
jQuery中DOM操作实例分析
2015/01/23 Javascript
浅谈javascript 函数表达式和函数声明的区别
2016/01/05 Javascript
Javascript中关于Array.filter()的妙用详解
2016/12/04 Javascript
AngularJS中使用ngModal模态框实例
2017/05/27 Javascript
微信小程序使用slider设置数据值及switch开关组件功能【附源码下载】
2017/12/09 Javascript
vue 组件的封装之基于axios的ajax请求方法
2018/08/11 Javascript
js如何获取访问IP、地区、当前操作浏览器
2019/07/23 Javascript
vue-router结合vuex实现用户权限控制功能
2019/11/14 Javascript
javascript设计模式 ? 享元模式原理与用法实例分析
2020/04/15 Javascript
Python2.x版本中cmp()方法的使用教程
2015/05/14 Python
使用python遍历指定城市的一周气温
2017/03/31 Python
python 平衡二叉树实现代码示例
2018/07/07 Python
Python json模块dumps、loads操作示例
2018/09/06 Python
使用PyCharm创建Django项目及基本配置详解
2018/10/24 Python
python的内存管理和垃圾回收机制详解
2019/05/18 Python
Django 源码WSGI剖析过程详解
2019/08/05 Python
Python3.x+pyqtgraph实现数据可视化教程
2020/03/14 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
keras中的loss、optimizer、metrics用法
2020/06/15 Python
HTML5 绘制图像(上)之:关于canvas元素引领下一代web页面的问题
2013/04/24 HTML / CSS
HTML5、Select下拉框右边加图标的实现代码(增进用户体验)
2017/10/16 HTML / CSS
俄罗斯便宜的在线服装商店:GroupPrice
2020/04/10 全球购物
Tomcat Mysql datasource数据源配置
2015/12/28 面试题
新闻专业本科生的自我评价分享
2013/11/20 职场文书
酒后驾驶检讨书
2014/01/27 职场文书
哈弗商学院毕业生求职信
2014/02/26 职场文书
留学顾问岗位职责
2014/04/14 职场文书
乡镇党员干部四风对照检查材料思想汇报
2014/09/27 职场文书
CSS 伪元素::marker详解
2021/06/26 HTML / CSS
python pygame 开发五子棋双人对弈
2022/05/02 Python