欢迎光临
我们一直在努力

Python + FontTools 自动生成字体子集工具 & FontForge 实现字体加粗

Python + FontTools 自动生成字体子集工具 & FontForge 实现字体加粗

  • 一、创建项目目录
  • 二、创建虚拟环境
  • 三、安装依赖
  • 四、核心脚本 font_subset_core.py
  • 六、打包 EXE
  • 七、 字体加粗
    • 安装 FontForge
    • 设置
    • 导出
  • 八、智能字体子集.bat
  • 参考资料

一、创建项目目录

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 这个要自己调看效果 在这里插入图片描述

导出

将选中字符导出为字体文件(警告什么的,反正也不会处理,直接跳过) 在这里插入图片描述

八、智能字体子集.bat

FontSubset.exe 辅助脚本 在 FontSubset.exe 所有目录创建文本文件,复制粘贴如下内容,然后文件改名为 智能字体子集.bat

@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion

title FontSubset 智能拖拽脚本
mode con cols=120 lines=32
color 07

goto main
:fail
color 0C
title [ERROR] FontSubset 智能拖拽脚本
::echo %~1
for %%i in (%*) do echo %%i
echo ===============================================
exit /b 1

:main

echo.
echo ===============================================
echo FontSubset 智能拖拽脚本
echo ===============================================
echo 用法: 将此脚本与 FontSubset.exe 放在同一目录下
echo 1. 拖入一个 .ttf 文件:自动查找同目录同名 .txt 文件
echo 2. 拖入一个 .txt 文件:自动查找同目录同名 .ttf 文件
echo 3. 同时拖入一个 .ttf + 一个 .txt:直接使用这两个文件执行(文件名无需相同)
echo.
echo 例如:
echo 拖入: game.ttf 自动查找 game.txt
echo 执行: FontSubset.exe game.ttf game.txt
echo
echo 拖入: 楷书.ttf + game.txt
echo 执行: FontSubset.exe 楷书.ttf game.txt
echo ===============================================
echo.

set "EXE=%~dp0FontSubset.exe"

if not exist "%EXE%" (
call :fail "【错误】 找不到 FontSubset.exe"
pause
exit /b
)

if "%~1"=="" (
call :fail "【错误】 请拖入 .ttf 或 .txt 文件"
pause
exit /b
)

set "TTF="
set "TXT="
set "BASE_DIR="
set "BASE_NAME="

:loop
if "%~1"=="" goto check

set "FILE=%~1"
set "EXT=%~x1"

if /i "%EXT%"==".ttf" (
set "TTF=%FILE%"
if not defined BASE_DIR set "BASE_DIR=%~dp1"
if not defined BASE_NAME set "BASE_NAME=%~n1"
) else if /i "%EXT%"==".txt" (
set "TXT=%FILE%"
if not defined BASE_DIR set "BASE_DIR=%~dp1"
if not defined BASE_NAME set "BASE_NAME=%~n1"
)

shift
goto loop

:check

if defined TTF if not defined TXT (
for %%A in ("%TTF%") do (
set "TXT=%%~dpnA.txt"
)

if not exist "!TXT!" (
call :fail 【错误】找不到同名【txt】: !TXT!
pause
exit /b
)
)

if defined TXT if not defined TTF (
for %%A in ("%TXT%") do (
set "TTF=%%~dpnA.ttf"
)

if not exist "!TTF!" (
call :fail 【错误】找不到同名【ttf】: !TTF!
pause
exit /b
)
)

if not defined TTF (
call :fail "【错误】 没有找到 .ttf 文件"
pause
exit /b
)

if not defined TXT (
call :fail "【错误】 没有找到 .txt 文件"
pause
exit /b
)

echo 当前字体文件: %TTF%
echo 当前字符文件: %TXT%
echo ===============================================
echo.

"%EXE%" "%TTF%" "%TXT%"

echo.
echo 执行完毕
pause

参考资料

https://github.com/fontforge/fontforge Glyphr Studio(浏览器离线开源,轻量 AI 辅助) yeungchenwa / FontDiffuser (本地开源 AI 模型,批量生成风格变体)

字体家 AI 在线字体编辑器(最推荐新手) Lipi.ai Font Studio(海外在线,AI 批量变体专业)

赞(0)
未经允许不得转载:171主机测评 » Python + FontTools 自动生成字体子集工具 & FontForge 实现字体加粗
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址