使用 Rust 和 WebAssembly 遭遇图像尺寸上限
许多图像工具提供质量滑块,但政府规定通常要求文件大小低于特定限制,这是一个不同的问题。质量与文件大小之间的关系复杂,取决于多种图像属性和编码器设置。本项目旨在创建一个 HEIC 转换器,其不变量为输出文件大小必须小于或等于目标字节限制。基于浏览器的实现使用编译为 WebAssembly 的 Rust 以提高效率。一个关键的设计决策是仅对图像解码一次,保留有界图像对象,以避免为预览、旋转和转换进行冗余且昂贵的解码操作。该系统将“精确大小”定义为上限,意味着文件将小于或等于目标大小,而非恰好为特定字节数。这通过将目标在内部转换为字节进行所有比较,从而避免了用户界面中 KB 测量的歧义。对于 JPEG 转换,算法在受保护范围内采用二分搜索以寻找最佳质量设置。该搜索通过首先以最低质量进行编码,若文件过大则调整尺寸并重新搜索来优化。如果初始 JPEG 编码过大,系统将根据图像面积估算新的缩放比例,并在调整尺寸前应用一个小余量,同时使用高质量滤波器。PNG 转换是无损的,因此没有质量调节器;相反,通过调整尺寸来实现。这包括对大照片进行初始缩小,然后编码并比较,随后可能进入“增长回”阶段以利用更多的字节预算。转换为 JPEG 或无损 PNG 与压缩到不同字节目标的过程保持分离,以确保用户意图清晰。颜色信息,特别是 ICC 配置文件,在转换和压缩过程中尽可能予以保留。WebAssembly 接口设计得简洁明了,在返回图像字节的同时显式返回元数据,使 UI 代码与压缩逻辑分离。最后,系统使用真实的 HEIC 文件进行测试,以确保满足不变量(输出字节 ≤ 目标字节)、质量下限、尺寸及其他指标,防止数据从页面泄露。