Pillow如何调用Unifont字体正常绘制标签字符字形
问题说明
Unifont字体包含标签(Tags)、变体选择符(Variation Selectors)及其他常规归类为非打印字符的对应字形,这类字符位于字体文件末尾区段,在FontForge中可正常查看:
每个标签字符都配有可打印的矢量字形轮廓,单字符效果如下:
使用Pillow调用Unifont绘制文本时,常规CJK表意文字可正常渲染,但标签类字符完全不可见,复现测试代码如下:
from PIL import Image, ImageDraw, ImageFont text = chr(0x2A6B2) + " " + chr(0x0E0026) font = ImageFont.truetype("unifont_upper-14.0.04.ttf", size=64) image1 = Image.new("RGB", (256, 64), "white") draw1 = ImageDraw.Draw(image1) draw1.text( (0 , 0), text, font=font, fill="black") image1.save("test aa.png")
原因与可行方案
- 渲染失败核心原因:Pillow依赖的HarfBuzz文本整形引擎默认会跳过Unicode分类为
Other, Format (Cf)的格式控制字符,不会加载这类字符的字形。标签字符、变体选择符均属于该分类,因此常规draw.text()流程不会渲染对应字形。 - 方案1:手动提取字形绕过默认整形逻辑
不使用draw.text()的整段文本渲染流程,单独提取目标标签字符的字形位图,手动计算位置粘贴到画布上,可实现正常绘制,参考代码:from PIL import Image, ImageDraw, ImageFont font = ImageFont.truetype("unifont_upper-14.0.04.ttf", size=64) image = Image.new("RGB", (256, 64), "white") draw = ImageDraw.Draw(image) # 正常渲染普通可打印字符 normal_text = chr(0x2A6B2) + " " draw.text((0, 0), normal_text, font=font, fill="black") # 单独处理标签字符 tag_char = chr(0x0E0026) # 获取字形边界与偏移 left, top, right, bottom = font.getbbox(tag_char) glyph_w, glyph_h = right - left, bottom - top # 单独渲染字形到透明层 glyph_layer = Image.new("RGBA", (glyph_w, glyph_h), (255,255,255,0)) glyph_draw = ImageDraw.Draw(glyph_layer) glyph_draw.text((-left, -top), tag_char, font=font, fill="black") # 计算粘贴位置,接在已渲染的普通文本后方 paste_pos_x = int(font.getlength(normal_text)) image.paste(glyph_layer, (paste_pos_x, 0), mask=glyph_layer) image.save("render_result.png") - 方案2:修改字体属性重新导出
用FontForge打开Unifont字体文件,将所有标签、变体选择符对应字符的Unicode分类修改为普通可打印字符类别,重新生成TTF字体文件后,即可直接通过draw.text()正常渲染这类字符。
内容的提问来源于stack exchange,提问作者Terence Eden
相关产品推荐
相关产品推荐

