Python结合FontTools实现自动生成字体子集工具

 更新时间:2026年06月12日 08:49:30   作者:笑虾  
FontTools作为Python生态中最强大的字体处理库,它让你能够轻松解析、编辑和生成各种字体格式,这篇文章小编就来和大家介绍一下Python如何结合FontTools实现自动生成字体子集工具吧

一、创建项目目录

fonttools/

├─ font_subset_core.py
├─ build.bat
└─ venv/

进入目录:

cd /d F:\tools\fonttools

二、创建虚拟环境

创建:

python -m venv venv

激活:

venv\Scripts\activate

成功后命令行会出现:

(venv)

验证:

where python

输出应类似:

F:\tools\fonttools\venv\Scripts\python.exe

三、安装依赖

安装 FontTools:

python -m pip install fonttools

安装 PyInstaller:

python -m pip install pyinstaller

验证 FontTools:

python -c "from fontTools.subset import main;print('OK')"

输出:

OK

说明环境正常。

四、核心脚本 font_subset_core.py

import sys
from pathlib import Path
from fontTools.subset import main as pyftsubset_main
FONT_EXTS = {".ttf", ".otf"}
def read_text_auto(path):
    data = Path(path).read_bytes()
    for enc in ("utf-8-sig", "utf-8", "gbk", "gb18030"):
        try:
            return data.decode(enc), enc
        except UnicodeDecodeError:
            pass
    return data.decode("gb18030", errors="ignore"), "gb18030-ignore"
def sort_key(c):
    code = ord(c)
    if '0' <= c <= '9':
        return (0, code)
    if 'A' <= c <= 'Z':
        return (1, code)
    if 'a' <= c <= 'z':
        return (2, code)
    if 0x4E00 <= code <= 0x9FFF:
        return (4, code)
    return (3, code)
def make_unique_chars(text):
    chars = {
        c
        for c in text
        if not c.isspace()
        and ord(c) >= 32
    }
    return "".join(sorted(chars, key=sort_key))
def build_subset(font_path, chars_path, out_font_path):
    pyftsubset_main([
        str(font_path),
        f"--text-file={chars_path}",
        f"--output-file={out_font_path}",
        "--layout-features=*",
        "--glyph-names",
        "--symbol-cmap",
        "--legacy-cmap",
        "--notdef-glyph",
        "--notdef-outline",`
        "--recommended-glyphs",
    ])
def main():
    if len(sys.argv) < 3:
        print("用法: font_subset_core.exe 字体.ttf 文本.txt")
        return
    font_path = Path(sys.argv[1])
    text_path = Path(sys.argv[2])
    if not font_path.exists():
        print("字体文件不存在:", font_path)
        return
    if not text_path.exists():
        print("文本文件不存在:", text_path)
        return
    if font_path.suffix.lower() not in FONT_EXTS:
        print("第一个参数必须是字体文件:", font_path)
        return
    text, enc = read_text_auto(text_path)
    chars = make_unique_chars(text)
    chars_path = text_path.with_name(text_path.stem + "_chars.txt")
    chars_path.write_text(chars, encoding="utf-8")
    out_font_path = font_path.with_name(font_path.stem + "_subset" + font_path.suffix)
    build_subset(font_path, chars_path, out_font_path)
    print("处理完成")
    print("识别编码 :", enc)
    print("字符数量 :", len(chars))
    print("字符文件 :", chars_path)
    print("子集字体 :", out_font_path)
if __name__ == "__main__":
    main()

命令格式:

python font_subset_core.py 字体.ttf 文本.txt

测试:

python font_subset_core.py test.ttf test.txt

处理完成
识别编码 : utf-8-sig
字符数量 : 247
字符文件 : test_chars.txt
子集字体 : test_subset.ttf

自动完成

读取文本

去重

排序

生成 chars.txt

调用 pyftsubset

生成 subset.ttf

六、打包 EXE

使用 PyInstaller:

python -m PyInstaller -F --clean --collect-all fontTools --name FontSubset font_subset_core.py

参数说明:

-F               单文件
--clean          清理缓存
--collect-all    打包 FontTools 全部依赖
--name           EXE名称

打包完成:

dist/
└─ FontSubset.exe

FontSubset.exe 用于根据游戏文本自动生成字体子集。第一个参数为原始字体文件(支持 .ttf.otf),第二个参数为文本文件(.txt)。程序会自动读取文本内容、提取所有可见字符、去重排序、生成字符集文件,并调用内置的 pyftsubset 生成子集字体。

使用方式:

FontSubset.exe FZBWKS.ttf all_text.txt

执行后会生成:

all_text_chars.txt     // 去重后的字符集
FZBWKS_subset.ttf      // 生成的子集字体

适用于传奇游戏、手游项目、UI字体优化等场景,可大幅缩小字体体积,同时保留项目实际使用到的全部字符。

无需安装:

Python
FontTools
PyInstaller

用户机器直接运行即可。

七、 字体加粗

安装 FontForge

然后打开上面生成的字体子集。勾选如下红框可紧凑显示(忽略空格只显示有的字符)

设置

Ctrl + A 全选,然后调整字体实现加粗。中文选 CJK 字中空隙保留选 Retain

我用 6 em units 这个要自己调看效果

导出

将选中字符导出为字体文件(警告什么的,反正也不会处理,直接跳过)

以上就是Python结合FontTools实现自动生成字体子集工具的详细内容,更多关于Python FontTools字体子集的资料请关注脚本之家其它相关文章!

相关文章

  • Python如何处理异常报错方法(建议收藏!)

    Python如何处理异常报错方法(建议收藏!)

    开发程序其实就像预测天气一样,即使是代码的异常错误,也应该能预测且被控制,下面这篇文章主要给大家介绍了关于Python如何处理异常报错方法的相关资料,需要的朋友可以参考下
    2022-06-06
  • 对python的bytes类型数据split分割切片方法

    对python的bytes类型数据split分割切片方法

    今天小编就为大家分享一篇对python的bytes类型数据split分割切片方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • python通过post提交数据的方法

    python通过post提交数据的方法

    这篇文章主要介绍了python通过post提交数据的方法,涉及Python使用post方式传递数据的相关技巧,需要的朋友可以参考下
    2015-05-05
  • Python基于Socket实现简单聊天室

    Python基于Socket实现简单聊天室

    这篇文章主要为大家详细介绍了Python基于Socket实现简单聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • pytorch中torch.topk()函数的快速理解

    pytorch中torch.topk()函数的快速理解

    我们在做分类算法时,时常见到@acc1和@acc5的情况,@acc1比较容易实现,但是一直苦于@acc5算法的实现,在此为大家提供一种@topk的实现方法,这篇文章主要给大家介绍了关于pytorch中torch.topk()函数的快速理解,需要的朋友可以参考下
    2022-02-02
  • Python中使用gflags实例及原理解析

    Python中使用gflags实例及原理解析

    这篇文章主要介绍了Python中使用gflags实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • python3 mmh3安装及使用方法

    python3 mmh3安装及使用方法

    这篇文章主要介绍了python3 mmh3安装及使用方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • Python编写一个Excel批量处理的桌面实用脚本

    Python编写一个Excel批量处理的桌面实用脚本

    在办公自动化的需求越来越多的今天,用 Python 做一个属于自己的“批处理小工具”,能轻松帮你节省大量重复劳动,下面我们就来看看如何使用Python编写一个Excel批量处理的桌面实用脚本吧
    2025-11-11
  • 如何在Python 中使用 Luhn 算法验证数字

    如何在Python 中使用 Luhn 算法验证数字

    Luhn 算法验证器有助于检查合法数字并将其与不正确或拼写错误的输入分开,这篇文章主要介绍了在Python中使用Luhn算法验证数字,需要的朋友可以参考下
    2023-06-06
  • Python批处理更改文件名os.rename的方法

    Python批处理更改文件名os.rename的方法

    今天小编就为大家分享一篇Python批处理更改文件名os.rename的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10

最新评论