深度解析字体矢量数据编码:从字体轮廓到Token ID的转换实践


引言:字体数据的数字化革命

随着AI在文本生成、字体设计等领域的应用加深,将字体的矢量轮廓数据转化为可计算的Token ID序列变得至关重要。本文将通过一段Python代码,深入解析如何从字体文件中提取矢量路径,并将其编码为模型可处理的离散化表示。


代码核心功能概述

1. 字体矢量数据提取
  • 目标:从字体文件(如.ttf)中提取每个字符的矢量路径数据。
  • 关键步骤
    • 使用fontTools库解析字体文件的glyf表,获取字形轮廓。
    • 通过RecordingPen记录路径命令(如moveTolineTo等)。
    • 将路径数据压缩为JSON格式,便于存储和传输。
2. 矢量数据编码
  • 目标:将路径坐标和命令转换为数值化的Token ID序列。
  • 关键步骤
    • 定义词汇表(vocabulary),包含路径命令(如ML)、坐标增量编码(如+xy_10-xy_5)。
    • 通过gen_ttf_to_token_id函数将字符的矢量路径映射为Token ID序列。
3. 特征提取与模型适配
  • 目标:为模型提供结构化的输入数据,支持字体生成或风格迁移任务。
  • 示例应用:提取“永字八法”(侧、勒、弩等)的矢量特征,作为训练数据的基础。

代码详解:分模块解析


1. 字体数据提取与路径解析

函数:extract_all_glyph_vector_data
def extract_all_glyph_vector_data(font_path):
    font = TTFont(font_path)
    cmap = font.getBestCmap()  # 映射字符编码到字形名称
    glyph_set = font.getGlyphSet()
    file_content = []

    for char_code, glyph_name in cmap.items():
        glyph = glyph_set[glyph_name]
        pen = RecordingPen()
        glyph.draw(pen)  # 记录字形的路径命令
        character = chr(char_code) if char_code <= 0x10FFFF else f"U+{
     char_code:04X}"
        
        # 压缩路径数据为JSON格式
        file_content.append({
   
            "text": character,
            "unicode": f"U+{
     char_code:04X}",
            "font": compress_path_to_json(pen.value)
        })
    return file_content
  • 作用:遍历字体中的每个字符,提取其矢量路径并存储为JSON格式。
  • 关键点
    • RecordingPen记录路径命令(如moveTo((100, 200)))。
    • compress_path_to_json将路径命令转换为简化的JSON格式(如[{"M": [100,200]}, {"L": [200,200]}])。

2. 矢量数据压缩与解压缩

压缩函数:compress_path_to_json
def compress_path_to_json(data):
    command_map = {
   'moveTo': 'M', 'lineTo': 'L', 'qCurveTo': 'Q', 'closePath': 'Z'}
    compressed = []
    for cmd, params in data:
        cmd_short = command_map[cmd]
        points = []
        for param in params:
            points += list(param)  # 将坐标点展平为列表
        compressed.append({
   cmd_short: points})
    return json.dumps(compressed)
  • 作用:将路径命令(如moveTo((x,y)))转换为更紧凑的JSON格式。
解压缩函数:decompress_json_to_path
def decompress_json_to_path(compressed_json):
    command_map = {
   'M': 'moveTo', 'L': 'lineTo', 'Q': 'qCurveTo', 'Z': 'closePath'}
    data = json.loads(compressed_json)
    decompressed = []
    for item in data:
        cmd_char = next(iter(item))  # 获取命令字符(如'M')
        points = item[cmd_char]
        # 将坐标列表转换为元组
        tuples = [(points[i], points[i+1]) for i in range(0, len(points), 2)]
        decompressed.append((command_map[cmd_char], tuples))
    return decompressed
  • 作用:将JSON格式的数据还原为原始路径命令。

3. 词汇表生成与Token编码

函数:gen_voc
def gen_voc():
    voc = ["<|zero|>", "<|start|>", "...", "<|end|>"]  # 特殊标记
    # 添加十六进制字符(用于文本编码)
    for i in "0123456789abcdef":
        voc.append(i)
        for j in "0123456789abcdef":
            voc.append(i + j)
            # ...(递归添加更长的组合)
    # 添加路径命令和坐标增量
    for cmd in ["M", "L", "Q", "Z"]:
        voc.append(cmd)
    for xy in range(512):
        if xy == 0:
            voc.append("xy_0")
        else:
            voc.append(f"+xy_{
     xy}")
            voc.append(f"-xy_{
     xy}")
    return voc
  • 作用:生成包含路径命令、坐标增量和文本编码的词汇表。
  • 关键点
    • 坐标增量采用+xy_10/-xy_5形式,便于模型捕捉相对位置变化。
编码函数:gen_ttf_to_token_id
def gen_ttf_to_token_id(voc, path="simsun.ttf"):
    one_ttf = extract_all_glyph_vector_data(path)
    # 提取特征字(如“侧、勒”)的Token序列
    features = [char for char in one_ttf if char["text"] in ["侧", "勒", "弩", "趯", "策", "掠"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方佑

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值