游戏ttf字体瘦身脚本

news2024/9/25 7:21:37

游戏中通常会用到某种特定字体,而某些字体动则10+M,对某些游戏(尤其是小游戏)来讲是无法忍受的,此文章主要讲述上个项目中制作的字体裁剪脚本

工具git地址

  • 配置信息(config.json)
{	
	// 文本内容(可能为多语言表导出的内容)
    "txtFile": "gameText.txt",
    // 字体文件
    "fontFile": "江城圆体 600w_1.ttf",
    // 默认文字(英文字符,阿拉伯数字等)
    "defaultText": "",
    // 导出的相对路径
    "exportPath": "../client/assets/Bundles/Game/font/",
    // 裁剪后导出的字体名称
    "exportName": "font.ttf"
}
  • 文本内容(gameText.txt)
    文件内为游戏中使用到的文字,多语言项目为多语言表导出文件。
  • 脚本(fontShort.py)
    注释较全面,可自行理解。如有不解,请搭配AI。
import re
import json
from fontTools.ttLib import TTFont
from fontTools import subset

    

config = 'config.json' # 配置文件路径

# config配置
textFile = ''
fontFile = ''
defaultText = ''
exportPath = ''
exportName = ''

# 文本内容
gameText = ''


# 加载config文件
def _loadConfig():
    with open(config, 'r', encoding='utf-8') as file:
        content = file.read()
        jsonObj = json.loads(content)
        global textFile
        global fontFile
        global defaultText
        global exportPath
        global exportName

        textFile = jsonObj['txtFile']
        fontFile = jsonObj['fontFile']
        defaultText = jsonObj['defaultText']
        exportPath = jsonObj['exportPath']
        exportName = jsonObj['exportName']

# 加载TXT文件
def _loadText():
    with open(textFile, 'r', encoding='utf-8', errors='replace') as file:
        content = file.read()
    return content


# 去重
def _removeDuplicates(s):
    return ''.join(set(s))


# 检查字体文件中缺失的字
def _checkFontExits(str):
    noneStr = ""
    
    font = TTFont(fontFile)
    glyf = font["glyf"]

    for i in str:
        code = i.encode("unicode-escape").decode()
        if "\\u" in code:
            code = "uni" + code[2:].upper()
        if not glyf.has_key(code):
            dd = re.findall('[\u4e00-\u9fa5]', i)
            if(len(dd) > 0):
                noneStr += dd[0]
    if(noneStr == ""):
        return
    print("<---------------------------------------->")
    print("当前字体中缺失字: " + noneStr)
    print("<---------------------------------------->")

# 导出字体ttf
def _exportFont(textStr):
    font = subset.load_font(fontFile, subset.Options())
    exportFile = exportPath + exportName
    
    subsetter = subset.Subsetter()
    subsetter.populate(text = textStr)
    subsetter.subset(font)

    # 生成输出文件
    subset.save_font(font, exportFile, subset.Options())

    font.close()
    print("输出字体文件成功: " + exportFile)


def _main():
    _loadConfig()
    originText = defaultText + _loadText().replace('\n', '')
    print("去重前: ", originText)
    print("<-------------------->")
    gameText = _removeDuplicates(originText)
    print("去重后: ", gameText)

    _exportFont(gameText)

    _checkFontExits(gameText)

    print("subset done!")
    print("输入回车键继续")
    input()

_main()
  • 文件结构
    在这里插入图片描述
  • 脚本执行
    可以看出当前字体内还缺失文字
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1989223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用API(三)

对于常见API的学习&#xff0c;主要学习了关于时间和日期的传统和新增APi 目录 1.Math 2.System 3.Runtime 4.日期和时间 &#xff08;1&#xff09;JDK8前传统时间API [1] Date [2] SimpledateFormat [3]Calendar &#xff08;2&#xff09;JDK8后新增时间API [1]代替…

JeecgBoot低代码平台简单记录

BasicModal弹窗 Usage 由于弹窗内代码一般作为单文件组件存在&#xff0c;也推荐这样做&#xff0c;所以示例都为单文件组件形式 注意v-bind"$attrs"记得写&#xff0c;用于将弹窗组件的attribute传入BasicModal组件 attribute&#xff1a;是属性的意思&#xff0c;…

嵌入式学习之线程和同步互斥机制

一. 线程的概念 进程的上下文切换&#xff1a; a.上下文&#xff1a;运行一个进程所需要的所有资源。 b.上下文切换&#xff1a;替换原有内容&#xff0c;从访问进程A的所有资源切换到访问进程B的所有资源&#xff0c;是一个耗时操作。 c.为了提高系统性能&#xff0c;引入了一…

HCIP | 实验一

实验内容 配置 1.合理规划IP地址&#xff0c;启用OSPF单区域 R1 R2 R3 R4 R5 R6 2.R1-R2之间启用PPP的pap单向认证 R1 R2 3.R2-R3之间启用PPP的chap双向认证 R2 R3 4.R3-R5-R6之间使用MGRE&#xff0c;R3为hub端&#xff0c;R5&#xff0c;R6为spoke端&#xff0c;要求MGRE…

DS1302实时时钟(51单片机)

一、DS1302时钟 1.DS1302时钟介绍 2.芯片使用 使用芯片时首先要通过数据手册知道芯片功能&#xff0c;根据芯片功能应用。 3.实现DS1302功能 通过对配置寄存器使用DS1302的读写功能 二、实现DS1302读写 1.模块化编程框架 首先对DS1302端口重新定义&#xff08;换端口名字…

汽车电子推拉力测试机测试流程的详细步骤

在现代汽车技术迅猛发展的今天&#xff0c;汽车电子产品的可靠性已成为确保车辆性能和乘客安全的关键因素。标准下的键合线剪切试验&#xff0c;作为评估这些产品中关键连接点强度的一项测试&#xff0c;扮演着至关重要的角色。本文旨在深入探讨这一测试的重要性、实施流程及其…

Java学习Day20

Vue学习 nodejs的安装与环境配置 1.直接去官网下载合适版本的nodejs( https://nodejs.org/zh-cn/download/prebuilt-installer) 2.解压下载的安装包&#xff0c;将文件路径配置到系统变量的path中&#xff0c;然后确认后退出。可以使用终端来查看安装的nodejs版本。使用winR…

智能合约的未来:解析Web3在智能合约领域的创新

随着区块链技术的不断发展&#xff0c;智能合约已成为Web3生态系统中的核心组成部分。智能合约通过在区块链上自动执行合约条款&#xff0c;推动了去中心化应用&#xff08;DApp&#xff09;的广泛应用。它们的核心优势在于去中心化、透明和不可篡改&#xff0c;这使得合同执行…

uniapp切换同一个子组件时,钩子函数只进了一次

给子组件添加不同的 “key” 值&#xff0c;当 key 值改变时&#xff0c;Vue 会认为这是一个不同的组件&#xff0c;并重新创建它 props: ["L1Id"],// 方式1: 使用keycomputed: {// 切换子组件时,发现created、mounted等钩子函数只会进一次,或者用 keykey(){this.ref…

RAG私域问答场景超级详细方案(第一期方案)[1]:工业级别构建私域问答(知识处理、知识召回排序、搜索问答模块)

RAG私域问答场景整体夏详细方案(第一期方案):工业级别构建私域问答(知识处理、知识召回排序、搜索问答模块) 大模型性能的跳阶式增长给文本摘要、信息检索、信息抽取、语义问答等自然语言处理任务带来了卓越的性能提升。同时,LangChain 作为一种基于 LLM 的框架,能够快速…

【autoware】安装ros2 密匙gpg报错,443连接失败

443连接问题解决方法&#xff1a; 访问该网站 https://ping.chinaz.com 输入raw.githubusercontent.com可以得到解析出来的IP sudo vim /etc/hosts

Unity射击游戏开发教程:(31)制造一定追踪行为的敌人

在本文中,我们将介绍如何在两种敌人行为之间切换。本文是前两篇文章的延续,分别介绍了敌人躲避玩家射击以及敌人不断旋转并向玩家射击的情况。我只是介绍如何在这两种行为之间进行转换。 这种新的敌人行为的目标: 当不开火时,敌人可以躲避玩家的射击。射击时,敌人无法躲避…

lvs实战项目-dr模式实现

一、环境准备 主机名IP地址router eth0&#xff1a;172.25.254.100 eth1&#xff1a;192.168.0.100 clienteth0&#xff1a;172.25.254.200lvseth1&#xff1a;192.168.0.50web1web2 1、client配置 [rootclient ~]# cat /etc/NetworkManager/system-connections/eth0.nmconne…

使用FFmpeg实现摄像头RTMP实时推流

在当今的数字时代,视频直播已成为连接人与人之间的重要桥梁,广泛应用于在线教育、远程会议、娱乐直播等多个领域。随着技术的不断进步,人们对于直播的实时性、稳定性和高质量需求日益增加。为了实现高效的视频直播,选择合适的工具和协议至关重要。 RTMP(Real-Time Messagi…

Kotlin OpenCV 视频分析和对象跟踪60 MIL 对象跟踪

Kotlin OpenCV 视频分析和对象跟踪60 MIL 对象跟踪 1 OpenCV 对象跟踪算法2 Kotlin 引入依赖3 OpenCV 下载4 Kotlin OpenCV MIL 对象跟踪 1 OpenCV 对象跟踪算法 算法算法特点1 BOOSTING Tracker基于 AdaBoost 算法。适合于简单的对象跟踪任务。算法较老&#xff0c;在复杂场景…

LLVM理论篇之编译器结构

1、概述 编译器完成源程序到目标程序的翻译工作&#xff0c;这是一个复杂的整体过程。从概念上讲&#xff0c;一个编译程序的整体过程可以分为3个阶段&#xff0c;每个阶段将程序的一种语言表示形式转换成另一种语言表示形式&#xff0c;并且各个阶段在逻辑上是紧密相连的。典…

【C++】STL | list (链表)详解及重要函数的实现

目录 前言 总代码 ListNode类框架的建立 (成员与模板) list类的框架 普通构造 与 empty_init&#xff08;适合不同类型构造函数的小函数&#xff09; list的迭代器 引子 operator、operator--&#xff08;前置与后置&#xff09; operator 与 operator! operator* 与 …

基于主从Reactor模式的高性能服务器

服务器性能 百万并发&#xff1a;2核2G 2M Linux云服务器&#xff0c;2线程100并发请求&#xff0c;持续1000s&#xff0c;达到百万连接处理且0错误 高并发HTTP服务器项目&#xff1a;性能与功能性测试汇总-CSDN博客&#xff08;测试详细信息&#xff09; 主要通信逻辑分析 初…

专利申请后,如何支付年费?

专利申请后&#xff0c;如何支付年费&#xff1f;

Vue3项目创建及相关配置

Vue是一种用于构建用户界面的JavaScript框架。它采用了一种称为MVVM&#xff08;Model-View-ViewModel&#xff09;的架构模式。 MVVM是一种将用户界面与业务逻辑和数据分离的设计模式。它包括三个部分&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;表示应用程序…