从 SVG 到 icns:Karabiner-Elements 应用图标(v13 版)的构建与一键更新指南
【免费下载链接】Karabiner-ElementsKarabiner-Elements is a powerful tool for customizing keyboards on macOS项目地址: https://gitcode.com/gh_mirrors/ka/Karabiner-Elements
本篇指南以 files/icons/v13/KarabinerElements/README.md 为骨架,完整拆解 Karabiner-Elements 仓库中 v13 版 KarabinerElements 应用图标(icns)的更新流程:如何在 Icon Composer 中导出设计稿、如何用一条make命令完成 iconset 生成、压缩与产物分发。读完本文,你将掌握该仓库图标模块的目录组织、构建脚本(create-icns.sh/optimize-image.sh)的内部原理,以及图标产物最终如何被 AppIconSwitcher 在运行时切换使用。
一、背景:仓库中图标文件的组织方式
Karabiner-Elements 的图标资源统一存放在仓库根目录的 files/icons 下,按设计版本分组,目前包含三类设计目录:
v13/:本文主角,对应 002 编号图标;@Zabriskije/:另一位设计师的版本,对应 001 编号图标(见 files/icons/@Zabriskije/KarabinerElements/Makefile);Tamura/:早期版本。
每个版本目录内结构一致,以v13/KarabinerElements/为例:
files/icons/v13/KarabinerElements/ ├── KarabinerElements.icon/ # Icon Composer 工程(Assets + icon.json) │ ├── Assets/icon_512x512@2x.png # 1024×1024 源图 │ └── icon.json # 工程描述文件 ├── exported/ │ ├── KarabinerElements.png # 从 Icon Composer 导出的 1024×1024 PNG │ └── KarabinerElements.icns # 构建产物 ├── Makefile # 一键构建脚本入口 └── karabiner.svg # Inkscape 矢量源文件根目录的 files/icons/Makefile 会递归遍历所有子目录中的 Makefile 并依次执行:
all: @for f in `find */ -name Makefile`; do make -C `dirname $$f`; done因此,在files/icons目录下运行一次make,即可重建全部版本的图标。
二、标准更新流程:原文档的两步操作
原文档 files/icons/v13/KarabinerElements/README.md 给出了最核心的更新步骤,必须严格按顺序执行:
- 用 Icon Composer 打开工程并导出 PNG:打开
KarabinerElements.icon(Icon Composer.app 是 macOS 上编辑.icon图标工程的工具),然后将图片导出为exported/KarabinerElements.png。 - 在终端运行
make:进入files/icons/v13/KarabinerElements/目录(或直接在该目录打开终端),执行make命令。
make命令会读取exported/KarabinerElements.png,自动完成 icns 生成、压缩与分发(详见下文第三、四、五节)。需要说明的是,该流程依赖 macOS 自带工具链(sips、iconutil、Icon Composer)以及pngquant,请在 macOS 环境下执行;这也是整个仓库图标流程的前提。
三、make 到底做了什么:Makefile 逐行解析
files/icons/v13/KarabinerElements/Makefile 内容非常精简,共四步:
all: bash ../../scripts/create-icns.sh exported/KarabinerElements.png mv app.icns exported/KarabinerElements.icns # Copy files cp exported/KarabinerElements.icns ../../../../src/apps/share/Resources/icons/002-KarabinerElements.icns sips -z 128 128 exported/KarabinerElements.png --out ../../../../src/apps/share/Resources/icons/002-KarabinerElements.png bash ../../scripts/optimize-image.sh ../../../../src/apps/share/Resources/icons/002-KarabinerElements.png- 调用
create-icns.sh:以exported/KarabinerElements.png为输入,生成app.icns(生成细节见第四节); - 重命名产物:把生成的
app.icns移动到exported/KarabinerElements.icns,作为该版本的正式产物; - 分发 icns:将 icns 复制到共享图标目录
src/apps/share/Resources/icons/002-KarabinerElements.icns。文件名前缀002-是图标编号,同一目录下还存放着000-*、001-*等版本(EventViewer、KarabinerElements、MultitouchExtension 三个应用各有编号);共享目录的完整列表见 src/apps/share/Resources/icons; - 生成并优化 128×128 PNG:先用
sips -z 128 128从 1024×1024 源图缩放出 128×128 的小尺寸 PNG(用于菜单栏等场景),再交给optimize-image.sh压缩。
四、create-icns.sh:从单张 1024×1024 PNG 生成完整 iconset
files/icons/scripts/create-icns.sh 是核心构建脚本,其关键设计如下:
第一步:收缩并回填画布,保留安全边距
sips --resampleHeightWidth 824 824 $ICON1024 --out app.iconset/shrunk.png sips --padToHeightWidth 1024 1024 app.iconset/shrunk.png --out app.iconset/icon_512x512@2x.pngmacOS 会对图标四周进行圆角裁切,因此脚本先把 1024×1024 的源图缩小到 824×824,再用--padToHeightWidth透明填充回 1024×1024 画布。这样既保留了 1024×1024 的 Retina 分辨率,又为系统圆角遮罩预留了安全边距,避免重要图形被裁掉。
第二步:由基准图派生 10 个标准尺寸
sips -z 16 16 app.iconset/icon_512x512@2x.png --out app.iconset/icon_16x16.png sips -z 32 32 ... icon_16x16@2x.png sips -z 32 32 ... icon_32x32.png sips -z 64 64 ... icon_32x32@2x.png sips -z 128 128 ... icon_128x128.png sips -z 256 256 ... icon_128x128@2x.png sips -z 256 256 ... icon_256x256.png sips -z 512 512 ... icon_256x256@2x.png sips -z 512 512 ... icon_512x512.png覆盖从 16×16 到 512×512@2x(即 1024×1024)的全部 iconset 尺寸,满足 macOS 在不同 UI 场景下的显示需求。
第三步:压缩并打包
optimize-image.sh app.iconset/*.png iconutil -c icns app.iconset先用压缩脚本处理 iconset 内全部 PNG,再由 macOS 自带的iconutil将整个 iconset 打包成单一.icns文件(即app.icns)。打包完成后删除临时app.iconset目录。
五、optimize-image.sh:pngquant 无损压缩
files/icons/scripts/optimize-image.sh 负责对 PNG 做量化压缩,要点如下:
- 仅处理
.png后缀文件; - 使用
pngquant --skip-if-larger --ext .png --force,--skip-if-larger保证压缩后若体积反而变大则保留原图,--force允许原地覆盖; - 连续执行两轮(
for i in 0 1),进一步压榨体积; - 压缩前后用
stat -f '%z'对比字节数并打印before -> after变化,便于观察压缩收益。
需要注意的是脚本中通过set +e/set -e临时允许pngquant命令失败(例如未安装或文件无需压缩时),保证流程不中断。构建make时若未安装pngquant,此步骤会静默跳过,但不影响 icns 的生成。
六、.icon 工程文件:Icon Composer 的项目描述
files/icons/v13/KarabinerElements/KarabinerElements.icon/icon.json 是 Icon Composer 的工程描述,核心字段包括:
fill.automatic-gradient:系统自动渐变填充色,此处为蓝色extended-srgb:0.00000,0.53333,1.00000,1.00000;groups[0].layers[0]:图层引用了Assets/icon_512x512@2x.png(即 files/icons/v13/KarabinerElements/KarabinerElements.icon/Assets/icon_512x512@2x.png),并设置scale: 1.3放大绘制;groups[0].shadow:中性阴影,透明度 0.5;groups[0].translucency:半透明效果,值为 0.5;supported-platforms.squares:声明该图标面向 macOS 方形图标平台。
可以看出.icon不是简单图片,而是一个带图层、阴影、半透明与平台声明的组合工程——这也解释了为什么更新图标时要先用 Icon Composer 打开它重新导出 PNG,而非直接替换图片文件。矢量设计源文件 files/icons/v13/KarabinerElements/karabiner.svg(Inkscape 工程,图案为圆角深色底 + 白色 "KEY" 字样)则用于在编辑器中修改设计并导出到工程。
七、图标在应用中的运行时切换机制
构建产物被复制到src/apps/share/Resources/icons/后,应用在运行时按编号选择图标。相关调用链为:
- src/apps/AppIconSwitcher/src/app_icon_utility.cpp 中的
krbn_get_app_icon_number()读取图标配置并返回编号; - src/share/app_icon.hpp 中
krbn::app_icon类解析 JSON 中的number字段(示例格式为{"number": 0}),解析失败时回退到0; - 配置文件路径定义在 src/share/constants.hpp#L104-L107 的
get_system_app_icon_configuration_file_path():即/Library/Application Support/org.pqrs/config/karabiner_app_icon.json。
结合三个版本 Makefile 中002-、001-的命名规律可以推断:number0/1/2 分别对应仓库中不同设计师版本(Tamura / @Zabriskije / v13),AppIconSwitcher 据此在运行时切换 Dock 图标。这样图标构建与运行时选择解耦——重新构建某个版本的 icns 并覆盖src/apps/share/Resources/icons/下的对应文件,即可在不改动逻辑的情况下更新应用外观。
八、实操清单与注意事项
完整更新一次 v13 版 KarabinerElements 图标的可复现流程:
- (可选)用 Inkscape 编辑 karabiner.svg,导出 PNG 并更新
KarabinerElements.icon工程内的Assets/icon_512x512@2x.png; - 在 macOS 上用 Icon Composer 打开
KarabinerElements.icon,导出到exported/KarabinerElements.png; - 在
files/icons/v13/KarabinerElements/目录执行make; - 验证产物:
exported/KarabinerElements.icns与src/apps/share/Resources/icons/002-KarabinerElements.icns均已更新;002-KarabinerElements.png为 128×128 压缩版。
注意事项:
make必须在 macOS 上运行,依赖sips、iconutil与 Icon Composer(随 Xcode 提供);pngquant缺失不影响 icns 生成,但会跳过 PNG 压缩步骤;- 步骤 1(导出 PNG)是步骤 2(运行 make)的前置条件,跳过导出直接 make 会处理旧的 PNG;
- 若在
files/icons根目录执行make,会通过根 Makefile 级联重建所有版本的图标(v13、@Zabriskije、Tamura 等); - 若希望应用切换到其他版本图标,可通过系统配置
karabiner_app_icon.json中的number字段选择(实现见 src/share/app_icon.hpp)。
本文所有脚本与产物均可直接在仓库中查阅验证:构建脚本、压缩脚本、v13 版 Makefile、共享图标目录 与 AppIconSwitcher 实现。
【免费下载链接】Karabiner-ElementsKarabiner-Elements is a powerful tool for customizing keyboards on macOS项目地址: https://gitcode.com/gh_mirrors/ka/Karabiner-Elements
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考