在 Mac 上批量压缩 iOS @1x/@2x/@3x 图标、安卓多档 density、App Store/Play Store 截图。一套不破坏 Asset Catalog 的移动端开发图片压缩工作流。
移动端要发的是一整套资产矩阵 —— 这不是 Web 压缩工具擅长的场景。iOS 一张位图图标要出 @1x / @2x / @3x 三档,安卓一个 drawable 要出最多五档 density。再叠上一套 AppIcon 、三种显示尺寸的 App Store 截图、Play Store feature graphic —— Swift / Kotlin 还没开始编译,源资产就轻松上百 MB。
通用 Web 压缩器在这里行不通。Asset Catalog 与 res/drawable-* 按文件名严格绑定每个资产,改名就构建报错 。Xcode 的 actool 只做 无损 重编码,不会替你减字节;fastlane snapshot 也只按模拟器原生像素截图,不 resize 也不压缩。
这篇讲怎么用 Zipic —— 一款 macOS 原生图片压缩工具,支持 URL Scheme、AppIntents、文件夹监控 —— 来补这些缺口,过程中不动文件名、不改 res/ 结构。
Web 项目通常一份原图加一组 srcset。移动项目要原图加上整个 density 矩阵,每个文件都按命名规则钉死:
AppIcon.appiconset 里的 Icon.png、[email protected]、[email protected],每个 slot 都在 Contents.json 注册mipmap-mdpi/、mipmap-hdpi/、mipmap-xhdpi/、mipmap-xxhdpi/、mipmap-xxxhdpi/三个容易踩的细节:
.png / .jpg / .heic / .heif / .avci / .pdf —— 但不支持 WebP。 矢量资产走 PDF 并勾上 “Preserve Vector Data”。(ImageSetType reference)actool 不是有损压缩器。 它在编译期把 PNG 重编码成私有的 premultiplied BGRA 容器,最终发布的字节数取决于你导入的源文件。(Asset Catalog Format Overview)你需要一款能就地压缩、保留文件名、一次跑完所有 density 档位、对不该动的格式自动跳过的工具。
Apple 的 Human Interface Guidelines 把矩阵列得很清楚:
| Slot | Points | @2x | @3x | 备注 |
|---|---|---|---|---|
| iPhone app | 60 pt | 120×120 px | 180×180 px | 必须 |
| Spotlight | 40 pt | 80×80 px | 120×120 px | 搜索结果 |
| Settings | 29 pt | 58×58 px | 87×87 px | 设置列表 |
| App Store 营销图 | — | — | 1024×1024 px | sRGB、不透明,无 alpha,不要自己倒圆角 |
两条 HIG 规则第一次写 iOS 都容易翻车:
要做跨 iPhone / iPad / Mac / Watch 的 Liquid Glass 图标,Icon Composer(WWDC25 Session 361)输出一份分层的 .icon 文档加一张扁平的 1024 PNG 给 App Store Connect。Zipic 只处理那张扁平 1024 PNG,分层设计文件原封不动。
AppIcon 推荐的 Zipic 预设:
| 设置 | 值 | 原因 |
|---|---|---|
| Format | original(PNG) | Asset Catalog 不收 WebP |
| Level | 2–3 | 图标这种小尺寸看不出差别 |
| Save location | original | 就地覆盖,Contents.json 引用一字不变 |
| Resize | 关闭 | 永远不要改图标尺寸 |
把 AppIcon.appiconset 文件夹拖到 Zipic,里面所有 PNG 按当前预设处理一遍,文件名一字不差:
在 Xcode build phase 里调用 Zipic,URL Scheme 一行就够:
open "zipic://compress?url=$SRCROOT/AppIcon.appiconset&format=original&level=3&location=original"
location=original 是 Contents.json 不出错的关键 —— 文件名和相对路径完全不变。
安卓换了一套思路,按 dpi 分成五档 density,不是 iOS 的 “@2x / @3x”(屏幕密度文档):
| 档位 | DPI | 相对 mdpi 缩放 |
|---|---|---|
mdpi | 160 | 1.0×(基线) |
hdpi | 240 | 1.5× |
xhdpi | 320 | 2.0× |
xxhdpi | 480 | 3.0× |
xxxhdpi | 640 | 4.0× |
换成整数像素比 —— 从 ldpi(0.75×)到 xxxhdpi(4.0×),比例正好是 3 : 4 : 6 : 8 : 12 : 16 。从 Figma 按 “1×” 导出再放大时可以直接拿这套比例做对照。
Adaptive Icon 又叠了一层结构(Create app icons、AdaptiveIconDrawable):
普通 drawable(不是 adaptive icon 的层)的格式选择只有两件事要定:
跨五档 density 文件夹一次性 PNG → WebP:
open "zipic://compress?url=$PROJECT_DIR/app/src/main/res&format=webp&level=3&location=original"
Zipic 递归扫描整个目录,处理每张 PNG / JPEG,输出同名 WebP 副本(或直接覆盖原文件,看你的构建指向哪个版本)。矢量 .xml drawable 不会被处理。
主窗口里的输出格式选择器:
App Store(Screenshot Specifications,截至 2026-05):
| 显示尺寸 | 竖屏像素 |
|---|---|
| 6.9 英寸 | 1320×2868 |
| 6.5 英寸 | 1284×2778 |
| 6.3 英寸 | 1179×2556 |
App Store Connect 接受 .jpeg / .jpg / .png ,每个 listing 1–10 张 。
Google Play(Graphic asset rules):
| 资产 | 规格 |
|---|---|
| 应用图标 | 512×512 32-bit PNG(带 alpha),≤ 1024 KB |
| Feature graphic | 1024×500 24-bit PNG/JPEG,不带 alpha |
| 截图 | 24-bit PNG/JPEG;最短边 ≥ 320 px;最长边 ≤ 3840 px;长边 ≤ 短边 × 2 |
| 截图数量 | 每种设备类型 2–8 张 |
| TV banner | 1280×720 |
为什么这步要专门压一遍?因为 fastlane snapshot 按模拟器原生分辨率截图,fastlane deliver 按文件名匹配上传 —— 中间没有任何工具帮你 resize 或压缩。模拟器吐出来一张 1320×2868 的 PNG 经常 4–6 MB。
Zipic 一行 URL Scheme 同时搞定 resize 和压缩:
# 6.9 英寸 App Store 截图 → resize 后输出 JPEG
open "zipic://compress?url=$HOME/fastlane/screenshots/zh-Hans&format=jpeg&level=3&width=1320&height=2868&location=custom&directory=$HOME/store-uploads/ios-69"
# Play Store 截图 → 24-bit PNG,落在 320–3840 px 限制内
open "zipic://compress?url=$HOME/fastlane/metadata/android/zh-CN/images/phoneScreenshots&format=png&level=3&width=1080&height=1920&location=custom&directory=$HOME/store-uploads/play"
整个截图目录的 resize 流程 —— 设目标宽度,把文件夹拖进来,输出就能直接上传:
国内 Android 开发不止 Play Store —— Google Play 在国内不可用,发布渠道分散在华为应用市场(AppGallery)、小米应用商店、OPPO 软件商店、vivo 应用商店、腾讯应用宝等多家。每家对应用图标和截图的规格各有差异,截图几乎不能跨市场复用。
| 市场 | 应用图标 | 截图规格 | 截图大小 | 数量 |
|---|---|---|---|---|
| 华为应用市场 | 216×216 PNG,正方形 | 450×800(9:16) 竖屏 / 800×450 横屏,JPG/JPEG/PNG | ≤ 2 MB / 张 | 至少 3 张 |
| 小米应用商店 | 256×256 至 512×512 直角,JPG/PNG | 1080×1920 竖屏 / 1920×1080 横屏,PNG/JPG/JPEG/GIF/BMP/WEBP | ≤ 5 MB / 张 | 至少 3 张 |
来源:华为开放平台上架规范 与 小米开放平台开发文档。OPPO / vivo / 应用宝的具体数字接近小米一档(1080×1920 ≤ 5MB),上架前以各家最新文档为准。
两个细节容易踩坑:
# 出 216×216 PNG 给华为,512×512 给小米
open "zipic://compress?url=$HOME/store-uploads/icon-master.png&format=png&level=2&width=216&height=216&location=custom&directory=$HOME/store-uploads/huawei"
open "zipic://compress?url=$HOME/store-uploads/icon-master.png&format=png&level=2&width=512&height=512&location=custom&directory=$HOME/store-uploads/xiaomi"
国内市场的另一个差异是渠道仍以 APK 多见——虽然各家逐步支持 AAB,但许多国内分发管线(特别是小渠道、预装、分包加固)还在 APK 上跑。导出 APK 的同时记得给图标和截图准备一份单独通过 Zipic 压过的资产,避免直接复用 Play Store 的素材尺寸。
URL Scheme 调用很适合塞进 build phase 或 fastlane lane。但更省心的方案是不集成 —— 让 Zipic Pro 的文件夹监控盯着你工具链已经在写的目录:
~/Design/figma-exports/ —— 每张 PNG / JPEG 自动转 WebP~/fastlane/screenshots/ —— deliver 上传前先 resize + 压缩$DERIVED_DATA/.../*.png —— Xcode 模拟器构建出的截图$PROJECT_DIR/app/src/main/res/drawable-xxxhdpi/ —— Android Studio drawable 导出每个目录配独立预设:AppIcon 用无损 PNG、安卓 drawable 用 level 3 WebP、App Store 截图用 resized JPEG —— 不同目录同时跑,互不干扰。
设置在 Zipic → 设置 → 工作流 。打开静默模式,build script 触发的 URL Scheme 完全不会抢 Xcode / Android Studio 的焦点:
更深入的玩法见 macOS 自动化:用文件夹监控自动压缩图片 与官方文档 监控目录与自动压缩。
压缩只是一根杠杆。两个平台本身已经在做大量资产瘦身,靠谱的策略是和它们叠加,而不是替代。
iOS — App Thinning(WWDC15 Session 404、On-Demand Resources):
iOS 二进制限制(Maximum Build File Sizes):
__TEXT 段 ≤ 80 MB 。安卓 — App Bundle 限制(Maximum app size):
| 资产 | 上限 |
|---|---|
| AAB base module | ≤ 200 MB |
| 每个 feature module | ≤ 200 MB |
| 安装时下载总和 | ≤ 4 GB |
| On-demand + fast-follow 资产包累计 | ≤ 4 GB |
| 旧版 APK 上传 | ≤ 100 MB |
几条 Zipic 用户偶尔会问的”不要做”清单:
.car 文件。 Asset Catalog 是 actool 编译产物,动了 .car 会破坏运行时资源查找。一条设计建议:toolbar、tab bar、navigation chrome 这些位置,Apple HIG(Icons)建议优先用 SF Symbols 而不是自定义 PNG / PDF。SF Symbols 自动跟随 Dynamic Type、字重和 Dark Mode —— 二进制少塞资产,可访问性还更好。自定义资产留给品牌或语义真正必要的地方。
按格式怎么选 —— 何时 WebP 完胜、何时该上 HEIC、何时坚持 PNG —— 见 如何为你的项目选对图片格式。
国内移动开发的另一条主战场是小程序。不像 iOS / Android 原生 App 把图标、截图按设备分档发布,小程序的图片直接打进代码包内随版本下发——而每家小程序对包体的硬约束又比原生 App 苛刻得多,图片资产管理是”上线前会不会被打回”的关键变量。
| 平台 | 主包上限 | 总包(主+分包)上限 | 图片格式备注 |
|---|---|---|---|
| 微信小程序 | ≤ 2 MB(微信开放文档硬限制) | ≤ 30 MB(普通主体)/ 20 MB(服务商代开发) | iOS 微信 14.5 起支持 WebP;建议 PNG 一律转 WebP 入包 |
| 支付宝小程序 | ≤ 2 MB | 所有分包总计 ≤ 8 MB(最严苛) | 文档明确建议「图片放服务器,src 指网络路径」 |
| 抖音小程序 | 主包阈值约 4 MB(官方论坛给出超过即触发警告) | ≤ 20 MB | iOS 端只支持 WebP / AVIF(不支持 HEIF);Android 端 WebP / AVIF / HEIF 都支持 |
支付宝小程序的 8 MB 总包上限尤其需要注意——剔除代码、字体、图标后,留给图片资产的预算几乎只剩零头:
抖音小程序的 iOS 端只支持 WebP / AVIF 这一条容易让团队踩坑——开发同学随手丢进一张 HEIC(macOS 截图默认格式),iOS 抖音里直接显示不出来。把 macOS 上的截图拖进 Zipic、统一转 WebP,是规避这条坑的最稳做法。
一条入包前的固定预设是这样的:
# 小程序入包前批量:PNG / JPEG / HEIC → WebP,控制单张 ≤ 50 KB
open "zipic://compress?url=$PROJECT_DIR/miniprogram/images&format=webp&level=4&location=original"
level=4 在小程序图片这种”图标 / 引导 / 单色插画为主”的场景下比 level=3 更合适——视觉上看不出区别,体积能再砍 20-30%。
需要更激进的瘦身方案,把 Zipic 加进文件夹监控(miniprogram/images/),新拖进来的 UI 图秒级转 WebP,直接配合开发者工具的”上传”按钮做版本上传——不用再单独跑一遍构建脚本。
把上面的片段拼成一个 iOS + 安卓同仓小团队的真实工作流:
~/Design/exports/{ios,android}/ 。监控目录把 iOS 导出转 PNG level 3,安卓导出转 WebP level 3。AppIcon.appiconset 。归档前的 run-script phase 调 zipic://compress?url=$SRCROOT/AppIcon.appiconset&format=original&level=3&location=original ,提交到仓库的图标已经是压过的。assembleRelease 之后让 Zipic 处理 app/src/main/res —— 全员 WebP,9-patch 与矢量 drawable 自动跳过。~/fastlane/screenshots/ 。snapshot 截图落地后几秒钟内 resize + 压缩完毕,deliver 直接捡走,全程没有第二个工具碰过它们。没人再手动拉滑块。预设固化标准,监控目录自动执行标准,URL Scheme 是构建期的最后兜底。
准备把压缩塞进 iOS / 安卓的构建管线?下载 Zipic —— 免费版每天 25 张额度。下载即享 7 天完整 Pro 体验。Zipic Pro 解锁 URL Scheme 高级参数、AppIntents、文件夹监控和无限批量处理 —— 一次买断,无需订阅。

了解 Zipic 如何用 pngoptim 做 Mac PNG 压缩:稳定预设、APNG 处理、ICNS 工作流,以及可预期的批量结果。

Zipic 用 Google 的 libwebp 处理 WebP,但在发现 libavif 无法正确保留 iPhone HDR 照片信息后,自研了 avifoptim。两个截然不同的工程决策背后的逻辑。

gifski 是 Mac 上把视频转成 GIF 的好手,但它压不了已有的 GIF、不会批量处理、也不监控目录。本文讲的是 gifski 之外,Mac 上 GIF 工作流该靠谁。