关于 PNG 图片二次压缩,刚发现一件很有意思的事情。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
3dwelcome
V2EX    程序员

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

  •  
  •   3dwelcome 2022-02-23 16:06:57 +08:00 1939 次点击
    这是一个创建于 1372 天前的主题,其中的信息可能已经有所发展或是发生改变。
    ZIP/GZIP 是一种相对比较弱的压缩算法,PNG 里封装的是 ZLIB ,底层算法是相同的。所以有一堆 PNG 图片时,想直接压缩是完全压不动的。

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

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

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

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

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

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

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

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

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

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

    这点 7z 好很多。
    noe132
        13
    noe132  
       2022-02-23 16:35:32 +08:00
    png 的压缩也有压缩级别的。只是大部分软件并没有给你一个调节参数。建议用 apngopt 压一遍,用 7zip 15 iterarions 以上
    tsanie
        14
    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
        15
    tsanie  
       2022-02-24 11:13:50 +08:00
    @tsanie 嘴瓢,除 7z 以外
    3dwelcome
        16
    3dwelcome  
    OP
       2022-02-24 11:22:36 +08:00
    @tsanie 我 27 张图片里有相似图片,加一起确实能稍微提升一点压缩率。

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

    除非你是这种,5 张图片相互毫无关联那种。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     882 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 21:19 PVG 05:19 LAX 13:19 JFK 16:19
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86