最近在整理硬盘,手里有一个约 250GB 的照片库需要归档存放。因为都是原图,占用的空间实在不小,并且因为我要上传到云端,体积越大价格越贵,所以肯定是本地能压缩一点是一点,于是我开始寻找合适的压缩方案。
作为一个存档性质的照片集,我的核心要求是必须是无损压缩。所以,任何会改变哪怕一个像素、损失些许细节的有损压缩方案(比如转码成 WebP 或低画质 JPG)都被排除了。如果使用 7z 或 Zip 等通用压缩算法,不仅压缩率极低,而且过程非常缓慢。
经过一番搜索,我找到了 Dropbox 曾推出的 C++ 开源工具:**(Dropbox/Lepton)**。
Lepton 是一个专门针对 JPEG 图像设计的无损压缩工具。因为它能“读懂”JPG,所以在能够完全无损(能够还原每个字节,MD5、SHA一致)的前提下,平均能将文件体积再压缩 20% 左右,速度和压缩率都非常理想。
Lepton 三件套
方案确定了,但在实际使用中遇到了阻碍。
首先,Dropbox 的官方仓库已被存档。顺藤摸瓜,我找到了微软重构并开源的lepton_jpeg_rust版本。Rust 版本更具安全性,正好可以结合 Tauri 进行桌面端开发。
其次,Lepton 本体是 CLI 命令行工具。虽然我大可以写一个脚本遍历压缩,但总觉得不大优雅,不能直观的看到任务进行到了哪,压缩成效。此外,压缩成 .lep 格式后,由于.lep 非通用格式,Windows 系统无法直接预览和查看,需要手动解压回JPG后才可被图片查看器打开,后续我要找图、查看图片会非常麻烦。
既然现成的工具不够顺手,我搜了搜也没有人造好了这个轮子,于是我决定自己整一套Lepton工具。
1. 查看器:LepViewer 查看器
为了快速方便的先查看一下我用CLI压缩好的.lep文件,于是我先做了Lep查看器**LepViewer**来试试水,实现双击Lep文件即可打开查看。
测试结果符合预期,将 .lep 文件关联后,双击即可像打开普通图片一样进行浏览、缩放,无需手动解压。
2. 批量处理器:TinyLep 压缩工具
验证了查看功能后,我在 5 月 8 日顺势完成了批量压缩工具 **TinyLep**。
有了 GUI 界面,操作就直观多了。支持直接拖拽文件或文件夹,批量进行 JPG 与 LEP 的双向转换。界面上可以清晰地看到整体处理进度、每一张图片的压缩前后大小对比以及具体的压缩率。实测 1.36 GB 的照片集合,在开启 AVX 指令集构建的版本下,仅需58.49秒即可压缩完毕。
以下是关于启用AVX和不启用AVX指令集的性能对比
使用 480 张总计 1.36 GB 的 JPG 照片进行测试,兼容版 (x64) 与 AVX 指令集版的耗时对比如下:
| 操作 | x64 | AVX |
|---|---|---|
| 解压 | 41.38 | 39.28 |
| 压缩 | 1:01.64 | 58.49 |
注:计时为手动操作有误差,时间消耗主要在硬盘 I/O 读取上。
效果相当不错,我压缩我80GB照片集花了1小时整。
3. Windows缩略图插件:LepThumb 缩略图插件
原本以为到这里就大功告成了,但实际浏览那 250GB 压缩后的照片库时,我发现了一个致命问题:资源管理器里全是 LepViewer 的软件 Logo,没有缩略图供我查看。
虽然是存档级别的不常看,但偶尔需要检索找图时,没有缩略图快速筛选简直无从下手,我难不成还得一个个点击查找吗?于是这两天(5 月 8 日 - 9 日),我又制作了 Windows 系统的缩略图插件:**LepThumb**。
这也是制作过程中最恶心的一个,插件编译成 DLL 并注册到系统后,不仅缩略图死活不显示,甚至我加的日志也没有任何写入迹象,我在开发环境手动试着调用DLL,发现DLL正确的给我返回了缩略图没有任何报错——系统似乎根本没有加载这个 DLL。
经过漫长的排查丧心病狂的加调试信息均无效果,我一度怀疑是否是我注册方式不对,今天用左手开机让电脑不爽了?反复重启后均无效果,我服了,我手动写了一个脚本去模拟 Windows 资源管理器调用COM组件,在这次的调试信息中发现——是动态链接依赖的问题。在我的开发环境中存在了相关依赖,所以调用一切正常;但在资源管理器独立的运行环境中缺失了该依赖,导致 DLL 加载时直接退出,连写日志的代码都执行不到。
找到症结后,解决起来就很简单了。在 Cargo.toml 和.cargo\config.toml中配置静态链接,将依赖直接打包进 DLL 中:
[lib]
crate-type = ["cdylib"]
[build]
target = "x86_64-pc-windows-msvc"
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
重新编译并注册 DLL 后,缩略图终于成功在文件管理器中显示了出来。单张(15MB 左右的 JPG)生成时间大约在 0.25 秒,配合 Windows 自身的缩略图缓存,只有首次打开文件夹时会稍有延迟,后续浏览非常流畅。
附录/Q&A
Q1:既然要压缩,为什么不用 7z / ZIP / RAR?
A: 通用压缩算法对基于哈夫曼编码的 JPG 几乎无效(压缩率仅为 1%~2%)。本项目使用的是专门针对 JPG 内部 DCT 系数重组的算法,能实打实缩小 20%+ 的体积,可以这么理解,LZMA2是通用压缩算法,什么都能压,但是他们“看不懂”JPG,不知道如何表达使得体积更小。
Q2:为什么不用 Caesium / WebP 转码压缩?
A: 本项目是JPG的无损压缩,虽然说有损压缩能节省相当之多的空间,但是代价的不可逆损失了质量,本项目适合将原图压缩后存档长期保存。(而且如果不在意质量,你也完全可以有损压缩完后再使用本项目压缩啊,可以直接白嫖约20%的空间不损失任何质量)
Q3:JXL 也支持 JPG 无损重组,为什么不用 JXL,反而搞个“非主流”的 Lepton?
A: 两个原因:第一,性能与体积 Lepton 远比JXL好;第二,JXL 的桌面生态太烂
目前 Windows 资源管理器默认(原生)并不支持 JXL 缩略图,普通用户需要自行去应用商店手动下载安装可选扩展(且该官方扩展仅限 Win11 24H2 及以上版本,Win10 甚至无法安装),或者折腾第三方 WIC 插件。我的工具是直接打包 GUI + 看图器,抹平了这些所有的使用门槛。
具体可以看一下对比:
| 压缩算法 / 工具 | 实际耗时 | 压缩后体积 | 附加说明 |
|---|---|---|---|
| 本项目的 Lepton | 0.51 秒 | 13,383 KB | 耗时包含了压缩 + 二次解压校验是否是真无损的总时间 |
| JXL 默认无损 (-e 7) | 0.63 秒 | 13,981 KB | 纯压缩耗时 |
| JXL 极限无损 (-e 9) | 16.07 秒 | 13,966 KB | 耗时是默认的 25 倍多压了个15KB |
$ time ./cjxl.exe DSC00016.jpg output_max.jxl -e 9
JPEG XL encoder v0.11.2 332feb1 [AVX2,SSE2]
Note: Implicit-default for JPEG is lossless-transcoding. To silence this message, set --lossless_jpeg=(1|0).
Encoding [JPEG, lossless transcode, effort: 9]
Compressed to 13966.1 kB including container
real 0m16.075s
user 0m0.000s
sys 0m0.000s
$ time ./cjxl.exe DSC00016.jpg output.jxl
JPEG XL encoder v0.11.2 332feb1 [AVX2,SSE2]
Note: Implicit-default for JPEG is lossless-transcoding. To silence this message, set --lossless_jpeg=(1|0).
Encoding [JPEG, lossless transcode, effort: 7]
Compressed to 13981.0 kB including container
real 0m0.638s
user 0m0.000s
sys 0m0.015s
$ ./lepton_jpeg_util.exe DSC00016.jpg 1.lep
2026-05-09T09:24:38.446Z INFO [lepton_jpeg::structs::lepton_file_writer] compressing to Lepton format
2026-05-09T09:24:38.583Z INFO [lepton_jpeg::structs::lepton_file_writer] Number of threads: 8
2026-05-09T09:24:38.766Z INFO [lepton_jpeg::structs::lepton_file_writer] worker threads 984ms of CPU time in 150ms of wall time
2026-05-09T09:24:38.766Z INFO [lepton_jpeg::structs::lepton_file_writer] decompressing to verify contents
2026-05-09T09:24:38.955Z INFO [lepton_jpeg_util] compressed input 17414140, output 13703659 bytes (compression = 27.1%)
2026-05-09T09:24:38.956Z INFO [lepton_jpeg_util] Main thread CPU: 187ms, Worker thread CPU: 2343 ms, walltime: 512 ms
在同等硬件下无损压缩一张 17.4MB 的原图,Lepton 的耗时仅为 0.51秒(且包含了二次解压的完整性校验)。而 JXL 就算是开启了极限压缩参数,体积依然比 Lepton 略大,且耗时显著更长。并且我提供了整套方案,使用体验甚至可以媲美未压缩JPG。
Q4:为什么要在已经有损的JPG基础上追求无损压缩?为什么不轻微降低质量来节省80%的空间?
A: 因为这个项目的初衷是“历史数据归档”。
很多人的硬盘里存有十几年来积累的海量 JPG 照片(且无法获取 RAW 原片)。在归档场景下,核心诉求是“保留文件当前状态的每一比特,绝不接受二次画质破坏”。有损压缩确实能省下 80% 的空间,但代价是永久且不可逆地改变了原图数据。
举个通俗的例子:假设你发现了一幅受损的古画,它对你很有意义。虽然它从被发现起就是有损的,但我选择把它妥善装裱在画框里无损保存,这完全是可以理解的。当然,任何人都有权利选择如何处置自己的东西,哪怕是把它揉成一团塞抽屉里。
再比如,我有一段 30年前绝版的老旧 MP3 音频,我当然可以直接把它再压缩一遍省空间,但面对珍贵的历史记忆,这种永久性的二次破坏是令人难以下手的。本工具服务的就是这群希望“既能节省空间,又能保证解压后校验值分毫不差”的群体。
总结
至此,这套针对 JPG 的无损压缩“三件套”算是彻底完成了:
- **TinyLep**:批量无损压缩工具(可视化进度与压缩率)。
- **LepViewer**:即时图片查看器(双击直接查看
.lep文件)。 - **LepThumb**:Windows 资源管理器缩略图插件。
最近一两年,大家应该都深有体会:固态硬盘和机械硬盘的价格都在疯涨。在这个存储成本翻倍的节骨眼上,如果你也有大量的 JPG 原图(比如摄影原片、家庭相册)需要长期归档,且不能接受降画质的有损压缩,那强烈建议你试试这套工具。它能实打实地帮你省出约 20% 的空间(在一些信息熵低的图片里,压缩率甚至能达到夸张的 49.8%)。几十数百 GB 的空间,就这么白嫖出来了。
该项目本质上就是使用时间换空间,用压缩、解压的时间换更小的空间,这才是对现代PC的过剩性能的一个好的利用方式(也就压缩、解压的那几毫秒,大部分时间是在读取上)。在现在电脑面前这点开销压根算不上什么,不过如果需要经常导入第三方软件比如PS可能会比较麻烦,建议是压缩需要长期存档的部分。
⚠️ 当然,也要说说局限性:
由于 .lep 不是通用格式,如果你需要经常把照片导入 PS、PR 等第三方软件进行后期处理,每次解压会比较繁琐。因此,它最完美的适用场景是“冷数据/温数据长期存档”。
如果有需要,可以去仓库里的LepViewerReleases | TinyLep Releases里获取编译好的EXE。MacOS、Linux需要自己编译了,没Mac机器,懒得去Linux下再编译一份。
目前项目已经开源,感谢微软团队开源的对 Lepton 工具的 Rust 移植与重构 lepton_jpeg_rust。
赞赏
如果这些工具对你有帮助,欢迎打赏支持:
更新日志
LepViewer 查看器
1.1.0
- 交互优化,滚轮缩放以鼠标为中心缩放,快速缩放以展示区域为中心点缩放。
- 优化图片打开效果,打开自动自适应窗口显示。
- 快速缩放组件使用DOM重写以保证一致性美观性。
- 信息丰富,底部状态栏会显示Lep文件大小。
- 优化另存为与复制逻辑,避免每次另存为、复制图片需要反复解压。
1.0.0
有最基础的放大缩小查看功能
门罗币钱包地址