关于 PNG 图片二次压缩,刚发现一件很有意思的事情。

2022-02-23 16:06:57 +08:00
 3dwelcome
ZIP/GZIP 是一种相对比较弱的压缩算法,PNG 里封装的是 ZLIB ,底层算法是相同的。所以有一堆 PNG 图片时,想直接压缩是完全压不动的。

可是当我把 PNG 图片转换成 base64 编码的 JS 文件后,竟然神奇般可以进行二次压缩!

虽然 ZIP 算法两次总压缩率,和一次 7z 超强压缩率基本持平。对我来说,能二次压缩,已经完全出乎意料。

也许是 ZLIB 之类算法的预设字典里,对于 base64 纯文字信息有特定优化?
1406 次点击
所在节点    程序员
16 条回复
vicalloy
2022-02-23 16:10:11 +08:00
转 base64 ,大小会膨胀 1/3 。你确定转 base64 后最终压完后会更小?
3dwelcome
2022-02-23 16:16:04 +08:00
@vicalloy 是的,就算膨胀后,也还是会比更小。

我的资源是 27 个 PNG 文件,在 PS 里直出,总共 104,325 字节。尝试用 ZIP 压缩,以失败告终。

写了一点打包代码,把 27 个 PNG 打包成一个 JS 文件,体积为 139,647 字节。

这时候用 zip 再次压缩,最终大小为 88,165 字节。
3dwelcome
2022-02-23 16:21:45 +08:00
我想了一下,应该是 PS 里直出,PNG 压缩算法有水分。但是因为算法冲突缘故,ZIP 是没办法直接去处理。

转换成 BASE64 后,就相当于变了一个维度,ZIP 算法又能再次生效了。

我知道很多人不信,一开始我自己也不信。但事实就是能压。

7z 极限压缩大小在 82k ,最终压成 88k 也不奇怪。
LeeReamond
2022-02-23 16:24:34 +08:00
@3dwelcome 生产意义是啥呢,你输出 webp,然后 base64 再压缩减小可能不错,png+zip 怎么搞都太大了
vicalloy
2022-02-23 16:26:27 +08:00
压缩率和图片内容有关系的。用 base64 ,是将 27 张图片作为一个整体压缩。
比如同一张图片你复制 27 份,用 PNG 格式大小是 1x27 。你转成 base64 再压,27 张图片的大小还是近似于 1 。
ScepterZ
2022-02-23 16:28:10 +08:00
有点意思,不过感觉是不是调调参数也能有类似效果,不懂压缩
3dwelcome
2022-02-23 16:28:25 +08:00
@LeeReamond 我测试的是 APP 的内置图标,PNG 无损压缩也够用了。

少个 15K ,也确实没啥意义,就是感叹一下,世界真奇妙。
weizhen199
2022-02-23 16:28:56 +08:00
对的,PS 上出的图片 PNG/JPG 都是,水分都感觉很大,至于是水分,还是别的地方出的被砍的太多。就不得而知了
vicalloy
2022-02-23 16:29:23 +08:00
说大小近似 1 是不对的,算法还没有这么智能。
adoal
2022-02-23 16:30:42 +08:00
@vicalloy 对……zip 是每个文件单独压缩后打包。可以测试一下原始 png 文件先打包(比如 tar ,甚至只为测试不为实用的话直接 cat 在一起)后再压缩。
rekulas
2022-02-23 16:31:25 +08:00
"把 27 个 PNG 打包成一个 JS 文件"
你可以再尝试下只打包不 encode 试试能否继续压缩
3dwelcome
2022-02-23 16:33:28 +08:00
@vicalloy 有道理,应该是 zip 打包算法没把 27 张看成一个整体,导致压缩无效的。

这点 7z 好很多。
noe132
2022-02-23 16:35:32 +08:00
png 的压缩也有压缩级别的。只是大部分软件并没有给你一个调节参数。建议用 apngopt 压一遍,用 7zip 15 iterarions 以上
tsanie
2022-02-24 11:12:30 +08:00
我试了下 android sdk 里 paper-card 示例中的 5 张图片,应该是 png 压缩级别高且优化输出后的。

| 项目 | 大小 |
| :---- | ----: |
| 加起来大小 | 1,676,149 |
| 7z 极限压缩 | 1,649,267 |
| zip 打包 | 1,650,731 |
| tar.gz | 1,651,711 |
| base64 后 zip 打包 | 1,660,597 |
| base64 后 tar.gz | 1,667,404 |

这个示例中 zip 直接打包反而是表现最好的了。
tsanie
2022-02-24 11:13:50 +08:00
@tsanie 嘴瓢,除 7z 以外
3dwelcome
2022-02-24 11:22:36 +08:00
@tsanie 我 27 张图片里有相似图片,加一起确实能稍微提升一点压缩率。

ZIP 单独打包,每个文件都是独立压缩,并没有前后文件关联性,压缩率就很低。

除非你是这种,5 张图片相互毫无关联那种。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/835949

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX