用Python的Pillow库绘制天城文

使用方法

使用Python的Pillow库可将程序中指定的文本绘制到画布(canvas)上,下面的代码是标准步骤,绘制一段天城文(devanagari)文本,并保存图片到本地。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PIL import Image, ImageDraw, ImageFont

unicode_text = u"प्राता रत्नं प्रातरित्वा दधाति"
font_file = "../DevanagariSanskrit.ttf"
font = ImageFont.truetype(font_file, 28, encoding="unic")

text_width, text_height = font.getsize(unicode_text)
canvas = Image.new('RGB', (text_width + 10, text_height + 10), "orange")

draw = ImageDraw.Draw(canvas)
draw.text((5, 5), unicode_text, 'blue', font)

canvas.save("unicode-text.png", "PNG")
canvas.show()

第3行是段梵文谚语,翻译成英文是an early riser earns good health,跟我们常说的「早睡早起身体好」差不多的意思,看来人类各个民族的情感是相通的。

第4行指定字体文件,Pillow库根据字体文件中的字形来打印相应的字符,可以用自定义的字体文件,也可以用系统自带的字体文件,Windows的天城文字体文件是C:\Windows\fonts\Nirmala.ttf。第7、8行代码先获取文本的长度和高度,用以确定画布的大小。接下来几行代码绘制文本,保存为图片并显示。

错误及解决办法

正常情况下,图片中的文本应该和代码中的显示效果一样。但我的Linux机器上显示正常,Windows下显示不正常。问题在于它只是把一个个字符排在一起,合字(ligature)规则没有体现。这个问题很早就有人提过:Bug in rendering Indic fonts · Issue #1089 · python-pillow/Pillow,从网友的讨论看,问题由未安装Raqm库所致。

Raqm依赖大名鼎鼎的FreeType和HarfBuzz进行底层的字体渲染(font rendering)和文字成形(text shaping)处理,还支持双向文本、连写体分项(script itemizaiton)等功能。所以Raqm支持大部分文字,而且特别关注于阿拉伯文、希伯来文、梵文等复杂文字的排版需求。在Ubuntu中可使用如下命令安装Raqm和它的依赖库:

1
sudo apt-get install libfreetype6-dev libharfbuzz-dev libfribidi-dev meson gtk-doc-tools

安装完后,用如下代码测试,如果返回True,则Raqm的功能正常。

1
2
3
>>> from PIL import features
>>> features.check('raqm')
True

Linux下安装这几个库很方便,但Windows下就比较麻烦。最简单的办法是在这里下载libraqm文件,将对应的dll文件直接复制到Python脚本所在的目录中,亲测可行。

参考

  1. Bug in rendering Indic fonts · Issue #1089 · python-pillow/Pillow
  2. ImageDraw support for Bangla language · Issue #3593 · python-pillow/Pillow
  3. python imaging library - How to install pre-built Pillow wheel with libraqm DLLs on Windows? - Stack Overflow
  4. python - Installing Raqm (Libraqm) Windows 10 - Stack Overflow