当前位置: 首页 > news >正文

字体子集化实践探索

最近项目rust生成PDF组件printpdf需要内嵌完整字体导致生成的PDF很大,需要做压缩,但是rust的类库allsorts::subset::subset不支持windows,所以做了一些windows下字体子集化的尝试

方案一:node.js做子集化
fontmin 缺点是也需要集成node环境,很多网络下载的字体都不支持

方案二:python做子集化
fontTools库的subset工具,兼容性最好的子集化工具,参数也最丰富
缺点:需要软件集成mini python环境,在低端电脑执行速度特别慢
pip install fonttools
可以直接用命令行执行
pyftsubset 原始字体文件路径 --text=需要保留的字符 --output-file=输出子集字体文件路径
完整的参数使用查看源码

from fontTools.subset import subsetdef create_font_subset(input_font, output_font, characters):subset_options = {'glyphs': characters}subset(input_font, output_font, subset_options)input_font_path = 'path/to/input_font.ttf'
output_font_path = 'path/to/output_font.ttf'
characters_to_include = 'abcdefghijklmnopqrstuvwxyz'create_font_subset(input_font_path, output_font_path, characters_to_include)

方案三:C#做子集化
Microsoft.Extensions.FontSubset 库

using System;
using System.IO;
using Microsoft.Extensions.FontSubset;class Program
{static void Main(string[] args){string fontPath = "path/to/font.ttf"; // 字体文件路径string[] characters = new string[] { "A", "B", "C" }; // 需要包含在子集中的字符列表string outputPath = "output.ttf"; // 输出文件路径using (FileStream outputStream = File.Create(outputPath)){FontSubset.BuildSubset(fontPath, characters, outputStream);}}
}

有一个fontsubset已经编译好可以直接用
fontsubset-console -c <字符集目录> -r <字符集文件匹配规则> -a -s <输入字体文件> <输出的字体文件>

方案四:java做子集化
拷贝了一个韩国人的项目,放到自己的仓库
启动一个java http服务,通过入参生成子集,第一次要400ms左右,后面执行越来越快几十ms
缺点:生成的字体仍然有1.3M;需要集成jre环境;放弃

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.FontSubsetGenerator;import java.io.IOException;public class SubFontByItextPdf {public static boolean subFont(String sourceFontFile, String destFontFile, String text) {long startTime = System.currentTimeMillis();try {String path = FontSubsetGenerator.GEN(sourceFontFile, destFontFile, text);System.out.println("result: "+path);} catch (DocumentException e) {e.printStackTrace();System.out.println("error");return false;} catch (IOException e) {System.out.println("error");e.printStackTrace();return false;}System.out.println("cost" + (System.currentTimeMillis() - startTime) + "ms");System.out.println("done");return true;}
}

方案五:用harfbuzz的工具类hb-subset
调用命令行直接执行,下载地址
hb-subset.exe --output-file=dest.otf C:\source.otf 你好呀
执行速度很快,字体子集化结果也比较理想
参数使用查看源码,也可以hb-subset.exe --help-all查看所有参数

http://www.lryc.cn/news/502735.html

相关文章:

  • A1017 基于Java+JSP+SQL Server+servlet的二手购物平台的设计与实现
  • Simdroid-EC:液冷仿真新星,助力新能源汽车电机控制器高效散热
  • C语言——实现并求出两个数的最大公约数
  • 今天你学C++了吗?——C++中的类与对象(日期类的实现)——实践与知识的碰撞❤
  • 享元模式的理解和实践
  • Unreal Engine 中的UI界面开发
  • Docker在Ubuntu和CentOS系统下的安装
  • EXCEL 关于plot 折线图--频度折线图的一些细节
  • Hive操作案例
  • C++ 内存管理和模板与STL
  • JDK8新特性:Stream
  • 前端传入Grule,后端保存到 .grl 文件中
  • 探索《Crypto Rumble》 游戏:经济模型篇
  • 【CSS in Depth 2 精译_072】第 12 章 CSS 排版与间距概述 + 12.1 间距设置(上):究竟该用 em 还是 px
  • Elasticsearch对象映射
  • Oracle 19c rac 补丁升级,从19.7 to19.22-集群
  • 机器学习--Kaggle的使用
  • 客户服务新突破,天润融通助力电动车企业实现数智化转型
  • 力扣题目 - 2931.购买物品的最大开销
  • 智慧化工园区自动化在线监测,建立产业链路数字安全网
  • 在Docker中运行MySQL的思考:挑战与解决方案
  • Linux中所有和$有关的操作
  • github操作学习笔记(杂乱版)
  • 学习思考:一日三问(思考篇)之路由表
  • 多个NVR同时管理EasyNVR:设置了“按需拉流超时”配置但没反应的解决方法
  • 基于Springboot的实验室管理系统【附源码】
  • 【Oracle11g SQL详解】常用字符串函数:`CONCAT`、`SUBSTR`、`LENGTH`、`INSTR` 等
  • 某养老产业公司管理诊断项目成功案例纪实
  • 自然语言处理基础及应用场景
  • 网页爬虫技术全解析:从基础到实战