resopt-cli 0.2.0

Plan, verify, and apply resource optimizations for Apple projects.
Documentation
# 全资源与 HEIC 分析验证 — 2026-09-15

## 实现与环境

resopt 0.2.0,macOS,Rust 1.97.1。新图片后端使用 Apple ImageIO 与 CoreGraphics;
正式编码前会实际检查 JPEG/HEIC 编码能力。系统 HEIC 编码服务在当前受限沙箱中不可用,
同一测试在沙箱外通过。没有调用 FFmpeg,也没有向真实 App 资源写入。

## 回归检查

- 30 项测试通过:4 项图片后端单元测试、7 项资源分析测试、19 项既有无损 PNG 工作流测试。
- Rust 文档示例编译通过;Clippy 使用 `-D warnings`;release 构建通过。
- 测试涵盖已有 HEIC、半透明 HEIC、Alpha 全满的 RGBA、16 位近乎不透明像素、小于 50 KiB 的图片、
  多帧 PNG 不被压成单帧、目录外资源、文件头与扩展名不一致、损坏图片及 HTML/JSON 生成。
- 此处记录本地验证;未运行远端 CI 或最低 Rust 版本测试。

## 完整真实资源快照

来源为 Lama Ludo `release/v3.9.3`,开始时 HEAD:`97e8895f03a56b3f2a41e3f318faf23f4fc9b1df`。
扫描排除已知源码/工具文件和缓存目录,其余资源文件连同目录元数据复制到临时快照。

| 项目 | 数量 |
| --- | ---: |
| 全资源清单文件 | 5,185 |
| 栅格图片 | 2,505 |
| PNG(按实际编码) | 1,941 |
| HEIC | 474 |
| JPEG | 8 |
| WebP | 82 |
| 图片成功解码 | 2,505 |
| HEIC 成功解码 | 474 |
| 仅清点、无优化后端的非图片文件 | 2,680 |

2,505 张图片均经过解码;多帧文件仅检查首帧,不生成单帧转换候选。
无透明像素时比较 JPEG 和 HEIC;有透明像素时不生成 JPEG 候选。
全量结果中,透明图片的 JPEG 候选数为 0。已有 HEIC 也实际解码并进入同样的比较流程。

质量档位为 75、85、95;输入大小下限为 0。默认 Alpha 误差上限为 `1/255 + 0.000001`。
总计 840 个文件有满足当前尺寸、透明状态、Alpha 阈值及体积条件的更小候选。
按每个文件取一个最小候选计算,可节省 **1,871,973 字节(约 1.79 MiB)源文件体积**。
其中体积最小的候选分别为 770 个 PNG、69 个 HEIC、1 个 JPEG;没有把多档候选收益重复相加。

HEIC 的 Alpha 并非无损:本次有 7,047 次 HEIC 试算因 Alpha 误差超过默认上限而被拒绝。
这些不是解码失败,报告保留体积、RGB 误差与 Alpha 误差数据,未把它们计入可采用收益。
当前阈值较保守,不能据此推断所有 HEIC 方案均无优化价值。画质仍需要人工检查原尺寸候选。

## 不变性与外部改动

5,185 个快照文件的 SHA-256 在分析后保持不变;所有真实项目图片的哈希也保持不变。
运行期间真实项目的 `lamaludo/Localizable.xcstrings` 出现了外部变更,未被覆盖或恢复。
本轮执行的编码操作只读取资源快照并写入分析输出目录。

## 消融验证

在另一个临时源码副本中分别移除两个行为:

1. 不再按实际像素判断透明度,把带 RGBA 的测试图片一律视为透明:不透明 Alpha 通道测试按预期失败。
2. 让透明图片也进入 JPEG 候选列表:格式分流测试按预期失败。

最终实现保留两个行为;上述试验未修改交付源码。

## 范围

音视频、动效、字体、压缩包、矢量图、数据、本地化及未分类文件均在清单中,但没有被宣称完成压缩优化。
新分析报告只提供候选;跨格式修改源文件、引用更新及恢复事务尚未接入 `apply`。
既有 `plan/apply/restore` 继续负责严格无损 PNG。未进行 App 编译、设备渲染或安装包体积测量。