Python日常小记 - 文字表情包制作器 for Wechat

Catalogue
  1. 1. 需求分析
  2. 2. GIF相关知识
  3. 3. Log
    1. 3.1. 20160904 ver 0.1 alpha
    2. 3.2. 编程过程及难点
    3. 3.3. 解决方案
  4. 4. 心得体会
  5. 5. 最新版代码
    1. 5.1. ver 0.1 alpha

没有系统性学习过Python相关的知识,但已经用它解决了不少问题了。不得不说,如果说编程语言家庭是个Armory Pod的话,Python绝对是仓库里最趁手的一套工具包,大概就是GTA武器包水平。

MATLAB是高价买来(租来)的24K镀金太空光学炮,只限单人使用,别人一起用会攻击自己。C语言是Lo Wang的武士刀,只有远古之神会用。Ruby是镶红钻的百变小樱魔棒。VB是究极无敌改进版玩具水枪,或者满级片手剑。Verilog……更像是放了低爆弹的金属风暴。暂时只用过这几种语言……随便tx一下。

进入正题,今天探讨的是一个特定的应用:如何用Python写一个微信文字表情包生成脚本。

需求分析

  • 输入中文或英文,输出微信可识别的GIF表情图
  • 可通过修改参数控制字体字号和文字颜色
  • 输出图片需与文字宽度成正比,留白不能过多影响微信中显示效果
  • 文字过长时提示截短或分为多行输出,限制最大字符数并限制行数为3行
  • *可直接将生成图片输出到系统剪贴板

GIF相关知识

GIF格式经历了1985年((⊙﹏⊙)b好久远)格式GIF87a到GIF89a的变革。现在网络上流行的GIF图片绝大多数是以后者进行编码的。

后者相较于前者优势主要有三点:透明背景、隔行扫描和动画序列。本文中主要涉及第一点。

Log

20160904 ver 0.1 alpha

解决了最基础的需求,即输入文字输出GIF文件

编程过程及难点

微信识别表情图片时,在移动端不限制文件格式,会通过色度和容差的方法去掉纯色背景,生成表情。在PC端则只支持GIF文件,会保留图片所有细节,如背景颜色等。因而,生成PC端GIF图片时,存在三个主要难点:

  1. 如何将文字无失真转化为图片
  2. 如何使输出GIF图片背景为透明
  3. 如何处理中文字符串()

解决方案

第一版程序写的简单,主要就是解决上述两个问题。
首先是文字变图片。PIL库的ImageDraw提供了text方案。尽管对于小字体存在一定异常,但本案例中并无大碍。
另外可以考虑的方案是通过一些与GUI结合的库实现,网上案例有使用pygame实现的,效果类似。

其次是图片存成透明GIF。由于GIF格式出现较早,对于透明度和色阶的支持不如其后辈png来得好^1。如今GIF仍旧能够盛行的一大因素就是其能支持简易动画,同时色彩较少的文件能有不错的文件体积。

个人理解GIF的透明度是以牺牲某一种特定颜色为代价的。例如本例中,就将纯黑色#000设为了透明色,因而图片中所有纯黑色的地方均会被优化为透明。

整体实现过程如下:

1
2
3
4
5
6
7
8
st=>start: 开始
e=>end: 结束
io=>inputoutput: 输入需要转化的文字
op1=>operation: 将文字转化为矢量图形
op2=>operation: 将矢量图形绘制到创建好的图片背景上
op3=>operation: 将绘制完的图形保存为GIF
st->op1->op2->op3->e

心得体会

这个程序挺简单的,但是还是花了接近半小时调试,主要原因是Python2.7的中文匹配utf8问题和GIF格式透明度定义问题。重新定义了颜色以后果然解决。关于Python的其它体会见矫情篇文章……

最新版代码

ver 0.1 alpha

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# -*- coding: utf-8 -*-
import os,sys,locale
from PIL import Image, ImageFont, ImageDraw
zihao = 100
img = Image.open('1.gif')
transparency = img.info['transparency']
text = raw_input(u'请输入需要转化的文字:\n'.encode('gb18030')).decode(sys.stdin.encoding or locale.getpreferredencoding(True))
im = Image.new("RGBA", (zihao*len(text) , zihao + 30), (0, 0, 0))
dr = ImageDraw.Draw(im)
font = ImageFont.truetype(os.path.join("fonts", "C:/Windows/Fonts/STZHONGS.TTF"), zihao) #华文中宋字体
dr.text((1, 1), text, font=font, fill="#111")
im.save(text + ".gif",transparency=transparency)
raw_input(u'表情已生成,任意键结束!')

程序所需模板图片:

效果:

Share Comments
多说已于2017年6月1日到期,此处不再提供评论功能。如需评论请使用About页面的disqus(GFW)或提交issue。
The previous duoshuo comment system stopped service. Please use disqus or submit issues to comment.