4、LVGL字体转换工具使用:在线转换工具、离线转换工具、转换参数配置详解
做嵌入式GUI开发,字体这块儿往往是新手最头疼的环节。LVGL本身不带字体,你得把PC上的字体文件“喂”给它,让它认识。怎么喂?就得靠字体转换工具。
这章我带你把这几个工具摸透。说白了,就是把.ttf或者.otf文件,转成LVGL能吃的.c源文件或者.bin二进制文件。我这些年用过不下十种转换方式,踩过不少坑,今天把最实用的经验给你。
4.1 在线转换工具:LVGL官方在线字体转换器
先说说在线工具。LVGL官方提供了一个网页版的字体转换器,地址我就不写了,你搜“LVGL online font converter”就能找到。我个人习惯在项目初期用它快速试效果。
使用步骤:
- 上传字体文件(支持.ttf、.otf)
- 设置字体大小(单位是像素,不是点)
- 选择要包含的字符范围(ASCII、中文、符号等)
- 配置压缩参数(后面细讲)
- 点击转换,下载生成的.c文件
嗯,这里要注意:在线工具生成的.c文件,默认是位图格式。每个字符对应一个像素矩阵。你想想看,如果包含几千个汉字,这个.c文件会非常大。我遇到过有人把整个GB2312字库转成.c,结果文件直接超过1MB,MCU根本放不下。
4.2 离线转换工具:LVGL Font Converter (GUI版) 与命令行工具
离线工具才是主力。LVGL官方提供了两种离线方式:一个是带界面的GUI工具(lv_font_conv),另一个是命令行版本。我强烈建议你掌握命令行版本,因为可以集成到自动化构建脚本里。
GUI工具特点:
- 可视化操作,适合初学者
- 支持拖拽字体文件
- 实时预览字符效果
- 但每次转换都要手动点,批量处理不方便
命令行工具优势:
- 可以写脚本批量转换
- 参数控制更精细
- 适合CI/CD流水线
- 跨平台(Windows/Linux/Mac都能跑)
我记得第一次用命令行工具时,被那一长串参数搞懵了。后来总结出一个最小可用命令模板,你直接套用就行:
lv_font_conv --font YourFont.ttf \
--size 16 \
--format lvgl \
--output output_font.c \
--range 0x20-0x7F \
--bpp 4
这个命令干了什么?加载字体文件,设置16像素大小,输出LVGL格式的.c文件,只包含ASCII字符(0x20到0x7F),每个像素用4位表示。
4.3 转换参数配置详解
参数配置是字体转换的灵魂。同样的字体文件,参数不同,生成的代码大小和显示效果天差地别。下面我把核心参数一个一个拆开讲。
| 参数 | 可选值 | 说明 | 我的建议 |
|---|---|---|---|
--size |
8~100+ | 字体像素大小,直接影响显示清晰度和文件大小 | 小屏用12~16,大屏用20~32 |
--bpp |
1, 2, 4, 8 | 每个像素的位数,决定抗锯齿效果 | 中文用4,英文用2或1 |
--range |
Unicode范围 | 指定要包含的字符区间 | 只包含用到的字符,别贪多 |
--format |
lvgl, bin, dump | 输出格式 | 小项目用lvgl,大项目用bin |
--no-compress |
无 | 禁用压缩,文件会变大但解码快 | Flash够大时用,提升渲染速度 |
关于bpp参数,我多说几句:
bpp全称bits per pixel。1bpp就是每个像素1位,只有黑白两色,没有抗锯齿。4bpp有16级灰度,抗锯齿效果很好。8bpp有256级灰度,效果最好但文件也最大。
你想想看,一个汉字在16像素下,大约16x16=256个像素。1bpp需要256位=32字节。4bpp需要256x4=1024位=128字节。8bpp需要256字节。如果包含2000个汉字,差距就是64KB vs 256KB vs 512KB。对于Flash只有1MB的MCU,这个选择很关键。
4.4 字符范围选择策略
这是最容易踩坑的地方。很多人图省事,直接把整个Unicode字库转进去,结果Flash爆了。我见过最夸张的案例,有人把整个CJK统一表意文字(约7万字)转进去,生成的文件超过10MB。
实际项目中,我建议这样选:
- ASCII字符: 0x20-0x7F(95个字符,必须包含)
- 常用中文: 0x4E00-0x9FFF(基本够用,约2万字)
- 数字和符号: 0x30-0x39, 0x00-0x2F等
- 特殊符号: 按需添加,比如温度符号℃(0x2103)
但说实话,2万个汉字还是太多了。更好的做法是:只包含界面中实际出现的字符。比如你的界面只有“温度”、“湿度”、“设置”这几个词,那就只转这几个字。LVGL支持动态加载字体,你可以把常用字做成一个字体文件,生僻字做成另一个,按需加载。
# 只包含特定字符的示例
lv_font_conv --font YourFont.ttf \
--size 16 \
--format lvgl \
--output small_font.c \
--symbols "温度湿度设置返回确认取消0123456789" \
--bpp 4
这个命令只转换了“温度湿度设置返回确认取消0123456789”这十几个字符,生成的.c文件可能只有几百字节。你想想看,这比转整个字库省了多少空间?
4.5 输出格式选择:.c vs .bin
LVGL支持两种输出格式:.c源文件和.bin二进制文件。两者各有优劣。
| 特性 | .c文件 | .bin文件 |
|---|---|---|
| 存储位置 | 编译进固件,放在Flash | 可放在Flash或外部存储(SD卡、SPI Flash) |
| 加载方式 | 编译时链接,直接使用 | 运行时通过文件系统加载 |
| 更新便利性 | 需要重新编译固件 | 只需替换文件,无需重新编译 |
| 适用场景 | 字体固定不变的小项目 | 需要OTA更新字体的大项目 |
我个人习惯:原型阶段用.c文件,方便调试。产品阶段如果Flash够用,也直接用.c文件,省去文件系统的麻烦。但如果你的产品支持多语言切换,或者需要后期更新字体,那必须用.bin格式。
4.6 本章知识体系
下面这张图帮你理清字体转换的整体流程和参数选择逻辑:
这张图把整个流程串起来了。从字体源文件开始,先选工具,再配参数,最后输出。你跟着这个决策树走,基本不会出错。
4.7 实战建议
最后给你几个实战建议,都是我用真金白银换来的经验:
- 先小后大: 先用几个字符测试参数效果,确认没问题再转全部字符。我曾经一次性转5000个汉字,结果bpp设错了,全部重来,浪费了20分钟。
- 保留原始字体文件: 别删.ttf文件。后期调整大小或参数时,你还需要它。我见过有人只保存了.c文件,想改大小发现原始字体丢了,又得重新下载。
- 版本管理: 把字体转换命令写成一个脚本,和代码一起提交到Git。这样别人拉下来就能复现,不用猜参数。
- 测试所有字符: 转换完成后,在LVGL模拟器上跑一遍,确保所有字符都显示正常。特别是中文,有些字体文件缺字,显示出来是方框。
--no-prefilter 参数。这个参数在某些字体上能改善小字号的显示效果。我是在一个2.4寸屏项目上发现的,不加这个参数,12px的宋体字边缘全是锯齿。