Lepton WASM:在浏览器里无损压缩解压,实现.lep在线查看


在上篇博文中,我分享了针对桌面端开发的Lepton 三件套(TinyLep、LepViewer、LepThumb)。那套工具帮我高效存档了250GB照片,且有着极佳的使用体验。

但随着我这几天的使用,新的需求出现了:如果我想要在在线相册里查看我的照片,浏览器是不认识Lep格式文件的啊,如何在浏览器里在线查看Lep文件呢?为了填补这个空白,我开发了 Lepton 家族的第四个成员:**Lepton WASM**。

为什么需要 Lepton WASM?

在 Web 环境下处理 .lep 文件面临两个核心挑战:

  1. 兼容性:由于.lep并不是通用格式,浏览器无法查看Lep文件
  2. 性能:Lepton 这种针对 DCT 系数重组的算法,计算量远大于普通压缩。如果用纯 JavaScript 编写解码器,速度会慢到令人绝望。

得益于 Rust 优秀的生态,我基于微软开源的 lepton_jpeg_rust 核心,利用 WebAssembly (WASM) 技术将其编译成了可在浏览器运行的二进制模块,该WASM文件完整版仅337KB,若只包括仅查看代码,WASM体积甚至可以精简到仅249KB,极其轻量还没我一张照片大

硬件加速:AVX To WASM SIMD

在桌面环境下,Lepton可以使用AVX2指令集提升速度,但在 WASM 环境下,我们无法直接操作 x86 的 256 位寄存器。

好在 WASM 标准已经引入了 SIMD (单指令多数据流) 支持。通过开启 simd128 特性,Lepton WASM 可以在浏览器中调用 CPU 的 128 位向量指令。实测开启 SIMD 后,**解码速度提升了约 25%**。这意味着在现代浏览器中,解码一张高清照片仅需不到一秒。

具体性能提升可以查看下表:

时间取三次的平均值,图片大小为1.45MB

压缩(SIMD 加速) 解压(SIMD 加速) 压缩(兼容版) 解压(兼容版)
平均时间 431 ms 421 ms 597 ms 577 ms
第一次耗时 438 ms 410 ms 596 ms 589 ms
第二次耗时 423 ms 437 ms 599 ms 555 ms
第三次耗时 432 ms 416 ms 596 ms 588 ms

PS:尽管 WASM 让浏览器具备了近乎原生的计算能力,但 Web 环境由于其沙盒机制与单线程调度的特性,性能表现会很大程度上受到环境干扰。

  1. 资源竞争:解压过程属于计算密集型任务,如果此时浏览器正在进行复杂的 DOM 渲染或 CSS 动画,可能会产生调度冲突,导致耗时异常波动(极端情况下可能出现长达数秒的延迟)。
  2. 异步建议:为了避免阻塞 UI 交互,我强烈建议在 Web Worker 中运行编解码逻辑。这样即使是在进行高负载计算,页面依然可以保持丝滑滚动。
  3. 场景选型:Web 版的核心意义在于零依赖、即时预览、小规模快速处理,给跨平台查看兼容性做个兜底。如果你有数以万计的照片需要进行大规模批处理,桌面端的 TinyLep 具备无可比拟的性能优势。

极简的使用方法

为了兼顾不同的使用场景,我准备了两个版本的包:

  • **Viewer (查看版)**:精简掉所有编码代码,体积极小。适合只需要在网页展示图片,不需要在线压缩的场景。
  • **Full (全能版)**:包含完整的编解码能力。你可以直接用它做一个在线压缩工具,所有计算都在用户本地浏览器完成。

为了让展示 .lep 文件像展示原生图片一样简单,我利用 Web Components 封装了一个自定义标签 <lep-img>,无需进行复杂的配置,只需要引入JS,然后再使用自定义标签<lep-img>即可插入图片

<lep-img src="images/my_photo.lep"></lep-img>

目前大部分主流的浏览器都支持SIMD,本项目可以启用SIMD加速处理,这是目前的支持情况:

  • Chrome ≥ 91 (2021年5月)
  • Firefox ≥ 89 (2021年6月)
  • Safari ≥ 16.4 (2023年3月)
  • Node.js ≥ 16.4 (2021年6月)

为了照顾一些老版本浏览器,本项目分为SIMD加速版和兼容版,可以通过在JS里使用wasm-feature-detect这个项目检测浏览器是否支持SIMD,然后自动加载最优版本。

示例:

import { simd } from "https://unpkg.com/wasm-feature-detect?module";

simd().then(isSupported => {
    if (isSupported) {
    	// 加载SIMD加速版
    } else {
    	// 加载兼容版
    }
});

你可以在控制台中输入以下JS代码查询浏览器是否支持SIMD:

import("https://unpkg.com/wasm-feature-detect?module").then(module => {
    module.simd().then(isSupported => {
        console.log(`SIMD: ${isSupported}`);
    });
});

或者你也可以访问WebAssembly SIMD 检测查询自己的浏览器是否支持SIMD

你可以访问此Demo查看Lep在线查看效果:Lep在线查看示例

Lep在线查看示例 Lepton 在线无损压缩、解压JPEG

这里不对JS代码方面做过多介绍,感兴趣可以查看Demo实现

Lepton 工具全家桶

至此,Lepton的有关工具又新增了一个成员,现在不仅可以本地批量压缩、快速查看,还可以在浏览器中浏览了。

  1. **TinyLep**:负责大规模批量压缩,把硬盘里的 JPG 瘦身。
  2. **LepViewer**:负责本地电脑的即时预览。
  3. **LepThumb**:负责 Windows 资源管理器的缩略图显示。
  4. **LeptonWASM**:负责在网页端、H5、在线相册中原生支持预览和处理。

如果你也有在线查看Lep图片的需求,或者是单纯只想在线压个JPG试试水,欢迎尝试本项目。

阅读上一篇博文:Lepton 三件套

赞赏

如果这些工具帮到了你,或者为你节省了昂贵的对象存储(OSS/S3)费用,欢迎打赏支持:

PayQrcode


赏
  目录