用Python修改字体字形与提取矢量数据:fontTools实战指南
字体设计与分析是NLP和视觉领域的交叉应用,而**fontTools
** 是一款强大的Python库,可以让我们直接操作字体文件的底层结构。本文将通过两个实用函数,展示如何修改特定字形和提取所有字形的矢量数据,帮助开发者快速上手字体编辑与分析。
一、函数1:修改字体字形(change_glyph
)
功能
- 将字体文件中指定字形(如"A")替换为新的矢量轮廓。
代码实现
from fontTools.pens.transformPen import TransformPen
from fontTools.ttLib import TTFont
from fontTools.pens.recordingPen import RecordingPen
from fontTools.pens.ttGlyphPen import TTGlyphPendef change_glyph(font_path, glyph_name, new_glyph_path):# 加载字体文件font = TTFont(font_path)# 获取 glyf 表glyf_table = font['glyf']# 确保字形存在if glyph_name in glyf_table.glyphs:# 记录原始轮廓(可选,用于对比)recording_pen = RecordingPen()glyf_table[glyph_name].draw(recording_pen, font)# 创建新轮廓new_glyph_pen = TTGlyphPen(font.getGlyphSet())# 定义新轮廓(此处为一个简单的矩形)new_glyph_pen.moveTo((100, 100))new_glyph_pen.lineTo((200, 100))new_glyph_pen.lineTo((200, 200))new_glyph_pen.lineTo((100, 200))new_glyph_pen.closePath()# 替换字形glyf_table[glyph_name] = new_glyph_pen.glyph()# 保存修改后的字体font.save(new_glyph_path)else:print(f"字形 '{glyph_name}' 不存在!")
关键步骤解析
- 加载字体:通过
TTFont
加载字体文件。 - 获取 glyf 表:
glyf
表存储字形的矢量轮廓数据。 - 记录原始轮廓:使用
RecordingPen
记录原始字形的路径数据(可选)。 - 生成新轮廓:通过
TTGlyphPen
定义新轮廓的坐标点(如矩形)。 - 替换并保存:将新轮廓写入
glyf
表,并保存为新字体文件。
应用场景
- 自定义字体设计:修改特定字符的形状(如Logo字体)。
- 修复字体缺陷:调整模糊或不规则的字形。
二、函数2:提取所有字形矢量数据(extract_all_glyph_vector_data
)
功能
- 遍历字体中所有字符,提取其矢量路径数据并保存为文本文件。
代码实现
def extract_all_glyph_vector_data(font_path, output_file):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()transform_pen = TransformPen(pen, (1, 0, 0, 1, 0, 0)) # 无变换glyph.draw(transform_pen)# 格式化输出character = chr(char_code) if char_code <= 0x10FFFF else f"U+{char_code:04X}"data = f"Character: {character} (U+{char_code:04X})\nVector Data: {pen.value}\n\n"file_content += data# 保存到文件with open(output_file, "w", encoding="utf-8") as f:f.write(file_content)
关键步骤解析
- 获取字符映射:通过
cmap
表将Unicode编码映射到字形名称。 - 遍历所有字符:逐个提取字形的矢量数据。
- 记录路径数据:使用
RecordingPen
获取字形的路径指令(如moveTo
,lineTo
)。 - 保存为文本:将所有字符的矢量数据写入文件,便于后续分析。
输出示例
Character: A (U+0041)
Vector Data:
MoveTo((100, 200))
LineTo((300, 200))
LineTo((200, 400))
ClosePath()
应用场景
- 字体逆向工程:分析字体设计逻辑或版权问题。
- 自动化处理:批量提取字形数据用于机器学习训练。
三、使用示例
# 修改字体中的"A"字形
change_glyph(font_path="simsun.ttf", # 输入字体路径glyph_name="A", # 目标字形名称new_glyph_path="modified.ttf" # 输出路径
)# 提取所有字形数据
extract_all_glyph_vector_data(font_path="simsun.ttf", output_file="simsun_vectors.txt"
)
四、注意事项
-
字体兼容性:
- 支持
.ttf
和.otf
格式,但 OpenType 字体需额外处理。 - 修改后字体需通过
fontTools
验证:python -m fontTools.validate modified.ttf
- 支持
-
性能优化:
- 处理大字体时,建议分批次处理或使用多线程。
-
版权问题:
- 修改商业字体需遵守版权协议,开源字体(如Google Fonts)更易操作。
五、扩展功能
1. 转换坐标系
通过 TransformPen
可以对字形进行缩放、旋转等变换:
# 缩放字形为原尺寸的50%
scale = 0.5
transform = (scale, 0, 0, scale, 0, 0)
transform_pen = TransformPen(pen, transform)
2. 可视化字形
使用 matplotlib
可视化字形轮廓:
import matplotlib.pyplot as pltdef plot_glyph(glyph):pen = PathPen(glyph)glyph.draw(pen)path = pen.pathfor element in path:vertices = element.verticescodes = element.codesplt.plot(vertices[:,0], vertices[:,1], marker='o')plt.show()
六、总结
通过 fontTools
,我们可以直接操作字体的底层矢量数据,实现字形修改、分析和自动化处理。无论是设计个性化字体,还是研究字体结构,这些工具都能提供强大的支持。立即尝试,探索字体设计的新可能!
相关文章:
用Python修改字体字形与提取矢量数据:fontTools实战指南
字体设计与分析是NLP和视觉领域的交叉应用,而**fontTools** 是一款强大的Python库,可以让我们直接操作字体文件的底层结构。本文将通过两个实用函数,展示如何修改特定字形和提取所有字形的矢量数据,帮助开发者快速上手字体编辑与分…...
数据库守护神-WAL机制
什么是WAL机制? WAL(Write-Ahead Logging,预写日志)是一种保证数据库操作原子性和持久性的核心机制。其核心原则可概括为: 任何数据修改操作,必须在对应的日志记录持久化到磁盘之后,才能将实际…...
[MySQL]数据库与表创建
欢迎来到啾啾的博客🐱。 这是一个致力于构建完善 Java 程序员知识体系的博客📚。 它记录学习点滴,分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 欢迎评论交流,感谢您的阅读😄。 本篇简单记录…...
工作记录 2015-05-27
工作记录 2015-05-27 序号 工作 相关人员 1 修改了指定短语的大小写的处理。 取消了一些逗号的处理。 郝 另: iCDA更新到了190的D:\Temp\CHTeam\iCDA_20150527下了 修改的文件: bin目录下是程序。 0223目录下是0223的一些设置和关键字。 更新…...
嵌入式汇编语言从小白到入门:从零开始的底层编程之旅
嵌入式汇编语言从小白到入门:从零开始的底层编程之旅 汇编语言作为最接近机器语言的编程方式,在嵌入式开发中扮演着不可替代的角色。本文将带你从零开始,逐步掌握嵌入式汇编语言的核心概念和实践技巧,最终能够独立编写简单的汇编程序并与C语言混合编程。 一、汇编语言与嵌…...
GPIO_ReadInputData和GPIO_ReadInputDataBit区别
目录 1、GPIO_ReadInputData: 2、GPIO_ReadInputDataBit: 总结 GPIO_ReadInputData 和 GPIO_ReadInputDataBit 是两个函数,通常用于读取微控制器GPIO(通用输入输出)引脚的输入状态,特别是在STM32系列微控制器中。它们之间的主要…...
不使用docker在本地安装与配置RAGFlow
RAGFlow 本地安装与配置(非docker方式) 一. 运行环境 windows10 CPU i7-12700F 2.10GHz内存 32GGPU RTX 4060 Ti 8G wsl 2 Ubuntu-22.04 1. 防火墙配置 wsl默认访问windows的本机服务需要配置防火墙,否则访问会失败。 windows10的防火墙配置: 打…...
sysfs 设备模型
介绍 Sysfs 设备文件系统与proc是同一类的文件系统,基于ramfs实现的内存文件系统。 1.1 为什么会有 sysfs?procfs 的局限性: 早期,Linux 使用 procfs 来提供内核与用户空间的交互接口。但 procfs 的设计不够层次化,设…...
彩讯携Rich AICloud与一体机智算解决方案亮相中国移动云智算大会
2025年4月10日,2025中国移动云智算大会在苏州盛大开幕,本次大会以“由云向智 共绘算网新生态”为主题,与会嘉宾围绕算力展开重点探讨。 大会现场特设区域展出各参会单位的最新算力成果,作为中国移动重要合作伙伴,彩讯…...
js触发隐式类型转换的场景
JavaScript 的隐式类型转换(Implicit Type Coercion)会在某些操作或上下文中自动触发,将值从一种类型转换为另一种类型。以下是常见的触发场景: 1. 使用 (宽松相等)比较时 会尝试将两边的值转换为相同类型后…...
《AI大模型应知应会100篇》第9篇:大模型的推理能力:原理与实现
第9篇:大模型的推理能力:原理与实现 摘要 近年来,随着大语言模型(LLM)的快速发展,其推理能力逐渐成为研究和应用中的热点话题。这些模型不仅能够生成流畅的文本,还能在一定程度上进行逻辑推理、…...
PODS_ROOT、BUILT_PRODUCTS_DIR和SRCROOT有什么区别
在 iOS/macOS 开发中,${PODS_ROOT}、${BUILT_PRODUCTS_DIR} 和 ${SRCROOT} 是三个核心的 Xcode 环境变量,它们的区别主要体现在 目录层级、内容归属 和 生命周期 上。以下是结构化对比和具体示例: 1. 定义与作用域对比 变量全称指向路径管理…...
Elasticsearch 系列专题 - 第六篇:高级功能与生态系统
Elasticsearch 不仅是一个强大的搜索引擎,还提供了高级功能和丰富的生态系统支持。本篇将深入探讨这些特性,并介绍如何与其他工具协同工作。 1. 高级特性 1.1 跨集群搜索(Cross-Cluster Search) 跨集群搜索允许查询多个独立集群的数据,适用于分布式系统。 配置远程集群:…...
python的web框架flask(hello,world版)
问题 最近需要基于一个开源项目进行二次开发,但是,现在的我主修java,从来没有接触过python的web开发。所以,我现在需要学习一下flask的hello,world。 python版本选择 通过这个Python版本状态页面Status of Python v…...
Vue学习笔记 - 逻辑复用 - 组合式函数
昨天参加了次视频面试,慢慢可以查漏补缺,继续学习Vue相关的知识,考虑找个实际的开源项目。 逻辑复用 组合式函数 在 Vue 应用的概念中,“组合式函数”(Composables) 是一个利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数。 无状态的…...
Caffeine的两种实现方式
咱们来具体对比一下你之前给的这段配置代码👇: java Configuration EnableCaching public class CacheConfig { Bean public CacheManager cacheManager() { CaffeineCacheManager manager new CaffeineCacheManager("myCache"); manager.…...
单细胞Seurat标准分析流程R语言封装
单细胞Seurat标准分析流程R语言封装 数据预处理与质控(线粒体基因比例计算、QC图表生成)标准化与高变基因筛选PCA/UMAP降维与聚类分析 差异表达分析模块自动化输出PNG可视化图表(质控小提琴图、UMAP聚类图)结果将保存在results/和figures/目录下(RDS对象、差异基因CSV表格…...
MOS管的发热原因和解决办法
发热来源 如上图,MOS管的工作状态有4种情况,分别是开通过程,导通过程,关断过程和截止过程。 导致发热的损耗主要有两种:开关损耗、导通损耗。 导通损耗 导通损耗比较好计算,根据驱动电压VGS值可以得到MOS…...
航顺HK32M070电钻解决方案:驱动未来,掌控无限可能
一、市场规模与增长:电动工具行业持续扩容,电钻需求强劲 全球电动工具市场规模近年来保持稳定增长,2023年市场规模已达288.5亿美元,预计2024年将突破304.9亿美元,年复合增长率达6.9%。中国市场表现尤为亮眼࿰…...
关于nacos注册的服务的ip异常导致网关路由失败的问题
文章目录 关于nacos注册的服务的ip异常导致网关路由失败的问题相关处理方案为方案一:手动指定服务注册的 IP 地址方法二:设置优先使用的网络段方法三:指定网络接口方法四:忽略特定的网卡 备注 关于nacos注册的服务的ip异常导致网关路由失败的…...
UI测试流程与关键注意点解析
在当今以用户体验为核心的数字时代,用户界面(UI)作为软件与用户交互的直接窗口,其质量直接影响着产品的成败。UI测试作为软件测试的重要组成部分,确保应用程序不仅功能完善,而且在视觉呈现和交互体验上也能满足用户期望。 作为软…...
从零开始构建智能聊天机器人:Rasa与ChatGPT API实战教程
引言:AI对话系统的时代机遇 在数字化转型浪潮中,聊天机器人已成为连接用户与服务的关键纽带。无论是客服系统中的724小时即时响应,还是智能家居中的语音交互,聊天机器人正在重塑人机交互方式。本文将通过详细教程,手把…...
SSM aop切面编程的学习
面向切面的AOP编程的引入: 1. 代码缺陷 - 非核心代码对核心业务功能有干扰,导致程序员在开发核心业务功能时分散了精力 - 附加功能代码重复,分散在各个业务功能方法中!冗余,且不方便统一维护! 2. 解决思路 …...
Zen 5白色装机优选,华硕X870 AYW GAMING WIFI W主板来了!
华硕X870/X870E系列主板再次迎来新成员——华硕X870 AYW GAMING WIFI W主板正式发售!专为追求高性价比游戏玩家而量身打造,延续AYW系列经典SPACE太空元素,配合大面积银白色散热装甲,打造出了极具金属质感和科技感的外观࿰…...
第Y1周:调用YOLOv5官方权重进行检测
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 文章目录 1、前言2、下载源码3、运行代码 1、前言 YOLOv5分为YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四个版本,这里以YOLOv5s为例。 2、下载源码 安…...
科技项目验收测试怎么做?验收测试报告如何获取?
科技项目从研发到上市需要一个很长的周期,并且在上市之前还有一个至关重要的交付过程,那就是项目验收,验收需要通过验收测试来呈现。科技项目验收测试是确保项目成功交付的关键步骤,那么是如何进行的呢?企事业单位想要获取科技项…...
C++笔记
C知识笔记 一、C概述 C是一种通用编程语言,它在C语言的基础上扩展而来,支持面向对象编程、泛型编程和过程化编程等多种编程范式。C具有高效、灵活、接近硬件等特点,广泛应用于系统软件、应用软件、嵌入式系统、游戏开发等领域。其强大的性能…...
国产Linux统信安装mysql8教程步骤
系统环境 uname -a Linux FlencherHU-PC 6.12.9-amd64-desktop-rolling #23.01.01.18 SMP PREEMPT_DYNAMIC Fri Jan 10 18:29:31 CST 2025 x86_64 GNU/Linux下载离线安装包 浏览器下载https://downloads.mysql.com/archives/get/p/23/file/mysql-test-8.0.33-linux-glibc2.28…...
如何应对“最后时刻任务堆积”(鼓包现象)
应对“最后时刻任务堆积”(鼓包现象)的方法包括:合理规划项目时间表、强化进度跟踪管理、明确任务优先级、有效的资源配置、提升团队沟通效率。其中,强化进度跟踪管理尤为关键。根据项目管理协会(PMI)的调查…...
C语言,原码、补码、反码
计算机是以补码来存储的 原码:正数最高位为:0;负数最高位为:1 (最高位是符号位) 正数:三码合一 如:2: 原码:0000 0000 0000 0000 0000 0000 0000 0010&#…...
Unifying Short and Long-Term Tracking with Graph Hierarchies—CVPR2023
Unifying Short and Long-Term Tracking with Graph Hierarchies 博客目录 Unifying Short and Long-Term Tracking with Graph Hierarchies摘要概况引言和相关介绍提出的观点 SUSHI核心构建跟踪图的层次结构构建分层剪辑分区 做第二个创新模块的需要将研究的重点从处理遮挡的问…...
深入解析 C# 中的模板方法设计模式
模板方法设计模式(Template Method Pattern)是行为型设计模式中的一种,它定义了一个操作中的算法框架,并允许子类在不改变算法整体结构的情况下,重新定义该算法的某些步骤。该模式通常用于类中包含一系列固定步骤的算法…...
0411 | 软考高项笔记:项目立项
在软考的项目管理知识体系中,技术可行性和经济可行性是项目立项阶段非常重要的两个分析维度。以下是对这两个考点的详细解释和记忆方法: 技术可行性分析 定义: 技术可行性分析是评估项目在现有技术条件和资源下是否能够成功实施。它主要回答…...
ubnetu 服务器版本常用端口和开放的端口对应的应用
1. 使用 netstat 查看端口与进程 netstat 是查看网络连接和监听端口的常用工具。通过以下命令可以列出所有开放的TCP/UDP端口及其关联的进程: sudo netstat -tulnp参数解析: -t:显示TCP端口。 -u:显示UDP端口。 -l࿱…...
【服务器端表单字符验证】
文章目录 一、实验目的二、核心代码实现三、调试关键问题四、总结 一、实验目的 掌握JSP表单验证在服务器端的实现技术,实现对用户输入字符的非空及长度为5的验证,返回对应提示信息并优化用户交互。 二、核心代码实现 前端表单 <form action"…...
pip 与 conda 的全面比较:Python 包管理的深度解析
在 Python 的生态系统中,包管理工具是开发者日常工作的重要组成部分。其中,pip 和 conda 是最常用的两种包管理工具。虽然它们在功能上有一些重叠,但在设计理念、功能范围、依赖管理、环境隔离等方面存在显著差异。本文将从多个维度深入…...
GTID不一致修复
背景描述 GTID模式下,mysql主从切换后,主从同步报错 Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION 1, but the master has purged bi…...
conda-pack打包环境到超算上。解决无法打包可编辑包
conda-pack 打包 使用 conda-pack 打包 Conda 环境可以将整个环境打包成一个独立的可移植压缩包,方便在其他机器上解压使用。以下是具体步骤: 1.安装 conda-pack 首先需要安装 conda-pack。你可以通过 conda 或 pip 安装: conda install …...
O(n)复杂度实现寻找数组第k小的数(快速选择算法)
非堆排序实现,利用快速排序思想实现的快速选择 package algorithm;public class Test {public int quickSelect(int nums[], int left, int right, int k){if (left right) return nums[left];int i left - 1, j right 1, x nums[left];while (i < j){do i…...
利用 RNN 预测股票价格:从数据处理到可视化实战
在金融领域,预测股票价格走势一直是众多投资者和研究者关注的焦点。今天,我们将利用深度学习中的循环神经网络(RNN)来构建一个简单的股票价格预测模型,并详细介绍从数据加载、预处理、模型搭建、训练到最终结果可视化的…...
前端从全链路角度分析性能
在面试中回答“从全链路角度分析性能优化”时,需覆盖用户请求到页面渲染的完整链路。以下是结构化回答框架,结合业界实践和最新优化策略: 一、网络传输优化 1. CDN与协议升级 ◦ 使用CDN缩短资源物理距离,结合HTTP/2/3的多路复用和头部压缩特性,提升资源加载效率(如We…...
2025年第十八届“认证杯”数学中国数学建模网络挑战赛【BC题】完整版+代码+结果
# 问题一:随机森林回归from sklearn.ensemble import RandomForestRegressormodel_rf RandomForestRegressor()model_rf.fit(X_train, y_train)# 问题二:LSTM时间序列预测from tensorflow.keras.models import Sequentialmodel_lstm Sequential()model…...
权限管控与数据安全:衡石ChatBot在钉钉中的合规部署指南
数据安全是ChatBot落地的第一道门槛 在数字化转型浪潮下,企业数据查询正从“专业BI工具”向“自然语言交互”跃迁。衡石ChatBot通过钉钉等企业IM工具,让业务人员以对话方式实时获取数据,极大提升了决策效率。然而,数据开放的同时…...
什么是生产管理看板?
简单来说,生产管理看板就是一种把生产过程“摆在明面上”的工具——它可能是贴在墙上的白板,也可能是车间里一块大屏幕,主要作用就是让生产信息一目了然。 这种看板广泛用在工厂、制造车间、或者办公室里,它把生产计划、任务进度、库存情况、设备状态等重要数据通通“晒”…...
YOLO学习笔记 | 一文详解YOLOv11核心创新与实践方法
===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== YOLOv11核心创新与实践 一、架构创新1. 模块升级与参数优化2. 多…...
198. 打家劫舍:动态规划
前言 本篇文章来自leedcode,是博主的学习算法的笔记心得。 如果觉得对你有帮助,可以点点关注,点点赞,谢谢你! 题目来源 198. 打家劫舍 - 力扣(LeetCode) 题目描述 思路 1.对于只有一个房间…...
算法基础模板
高精度加法 #include <bits/stdc.h> using namespace std; const int N10005; int A[N],B[N],C[N],al,bl,cl; void add(int A[],int B[],int C[]) {for(int icl-1;~i;i--){C[cl]A[i]B[i];C[cl1]C[cl]/10;C[cl]%10;}if(C[cl])cl; } int main() {string a,b;cin>>a&…...
【大模型LLM第十六篇】Agent学习之浅谈Agent loop的几种常见范式
anthropics agent https://zhuanlan.zhihu.com/p/32454721762 code:https://github.com/anthropics/anthropic-quickstarts/blob/main/computer-use-demo/computer_use_demo/loop.py sampling_loop函数 每次进行循环,输出extract tool_use࿰…...
[特殊字符] Spring Boot 日志系统入门博客大纲(适合初学者)
一、前言 📌 为什么日志在项目中如此重要? 在开发和维护一个后端系统时,日志就像程序运行时的“黑匣子”,帮我们记录系统的各种行为和异常。一份良好的日志,不仅能帮助我们快速定位问题,还能在以下场景中…...
【模拟电路】隧道二极管
与标准二极管相比,隧道二极管通过使用具有令人难以置信的大掺杂水平的半导体物质来工作,导致p-n结之间的耗尽层变得比最快的硅二极管窄约1000倍。 一旦隧道二极管正向偏置,整个p-n结开始发生称为电子流“隧穿”的过程。 在测试隧道二极管的…...