You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pillow如何检测所用字体是否包含指定字符的对应字形

Pillow检测字体缺失指定字符字形的实现方案

你可以直接通过Pillow封装的FreeType接口判断字符是否存在对应字形,不需要额外依赖其他第三方库,判断结果准确无误差。

方法1:读取字体字符映射表检测(推荐)

Pillow加载的TrueType/OpenType字体对象底层对接FreeType库,可以直接调用内置方法查询字符的字形索引:如果索引值为0,就代表当前字体没有该字符的对应字形,绘制时会自动 fallback 到.notdef字形(通常显示为?或者空心方块)。
该方法不需要实际绘制内容,提前就能完成判断,性能很高,适合批量文本处理场景。
对应实现代码如下:

from PIL import Image, ImageDraw, ImageFont

def is_char_supported(font: ImageFont.FreeTypeFont, char: str) -> bool:
    # 调用FreeType接口查询字符对应字形索引,返回0即无对应字形
    glyph_index = font.font.getcharindex(ord(char))
    return glyph_index != 0

image = Image.new("RGB", (100, 100), "white")
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("unifont_upper-14.0.04.ttf", size=16)

target_char = "𒀀"
if is_char_supported(font, target_char):
    draw.text((1, 1), target_char, font=font, fill="black")
else:
    print(f"当前字体缺失字符 {target_char} 的字形,可选择跳过绘制或切换备用字体")
    # 此处可添加切换备用字体的逻辑
    # fallback_font = ImageFont.truetype("对应支持楔形文字的字体文件路径.ttf", size=16)
    # draw.text((1, 1), target_char, font=fallback_font, fill="black")

image.save("cuneiform.png")

方法2:旧版本Pillow兼容方案

如果你使用的Pillow版本低于8.1.0(未暴露getcharindex接口),可以通过比较字符绘制边界的方式判断:当字体不支持某个字符时,调用getbbox返回的边界会和默认.notdef问号的边界一致。该方法存在小概率误判,优先使用第一种方案。
示例判断逻辑:

def is_char_supported_old(font: ImageFont.FreeTypeFont, char: str) -> bool:
    # 取缺失字符默认显示的?的边界框作为参照
    notdef_bbox = font.getbbox("?")
    char_bbox = font.getbbox(char)
    # ASCII问号本身直接返回支持
    if char == "?":
        return True
    return char_bbox != notdef_bbox

注意事项

  • 不要通过绘制后识别图像内容的方式判断是否缺字:不同字体的.notdef字形不统一,有的是问号、有的是空心豆腐块、有的是空白,识别误差很大。
  • 处理整段文本时可以逐字符调用检测方法,遇到缺字字符自动切换到提前加载好的备用字体,即可实现多字体自动fallback的排版效果。

内容的提问来源于stack exchange,提问作者Terence Eden

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 07:54:23