V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
BaseException
V2EX  ›  分享创造

[可能是]最好的压缩图片程序,使用 squoosh-cli 批量压缩图片

  •  
  •   BaseException · 199 天前 · 2121 次点击
    这是一个创建于 199 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文


    前言

    去年以前我写博客都没有压缩图片的意识,有时候文章加载的图片过多,有些图片过大就会导致浏览体验很不好。后来用惯了 squoosh 项目之后每次写文章都会压缩一下配图,主要是 squoosh 太优秀了,还是 freeware 。

    去年我有制作一个 squoosh docker 镜像,可以在本地轻松使用 docker 开启一个压缩图片的服务,但是那时每次都是一张一张图片的压缩,因为我每张图片都调整了一下 quality ,为的就是一个非常 suitable 的 size for local storage ,我自建的图床运行在本地,存储在本地 ssd 的,所以以前有这个想法也很正常。但是这次大量图片压缩的需求让我明白了批量的意义——尽管可能达不到图片压缩后的质量与存储大小的完美平衡点,但在写博客(图片质量)和本地存储都做一点妥协之后,带来极大的愉悦轻松感,这是非常值得的。

    去年那篇 squoosh 文章在此 做了一个 squoosh docker 镜像,写博客贴图直接在本地压缩文件,安全且高效

    友情提醒:squoosh 官方是有提供 web 服务的,地址在 https://squoosh.app 但是居然没有 Copy npx command 功能,不知道以前有没有。

    正文

    下面我讲讲如何使用 squoosh-cli 进行图片的批量压缩,之所以推荐在自建的 docker 容器中运行 squoosh-cli 命令,是因为容器里是 Linux 环境,命令行友好,不像 cmd 和 powershell 可能需要各种转义,引号,还有通配符问题。

    首先你可以删掉之前创建的 squoosh 容器,之前没有加 volume ,这次我们需要加一个 volume 映射。

    在运行 squoosh 容器的 linux 上先创建一个文件夹保存 squoosh 文件,路径最好有通过 samba 等协议挂载到资源管理器上。

    # mkdir -p /home/dk/squooshfiles
    

    下面启动 squoosh 容器,命令如下

    docker run -d --name squoosh \
        --restart unless-stopped \
        -p 7701:8080 \
        -v /home/dk/squooshfiles:/app/squooshfiles \
        dko0/squoosh:1.12.0
    

    解析:

    • 这将在容器中自动创建目录 /app/squooshfiles
    • 本地对 /home/dk/squooshfiles 的修改和容器中对 /app/squooshfiles 的修改将完全同步,所以请创建一个完全独立的 squooshfiles 目录,只用于 squoosh 批量压缩图片
    • docker hub 上的镜像我没有去更新,使用以前的就行,只需要多执行一个命令安装 squoosh cli 包,下文有提到

    然后进入容器安装 squoosh-cli npm 包,执行 docker exec -it squoosh ash 后进入

    # npm i -g @squoosh/cli
    

    我之前有尝试在本地 win 环境下安装这个,但是本地 node 版本已经 18 了,无法安装这个包,是因为 node 版本太新,所以我就干脆在这个容器上进行了。一个容器多用——压缩单张图片时用户可以网页上操作,多张图片压缩场景时,打开终端进入容器操作即可。

    安装完成之后执行 squoosh-cli --help 应能获取命令行帮助。

    squoosh cli help.jpg

    squoosh-cli 最有用的就是批量,另外强大的一点是也能直接复制使用网页上的配置,但可惜的是 https://squoosh.app 官方提供的这个服务没有 Copy npx command 功能了,所以感觉我这个容器镜像创建的刚刚好,自建后刚好满足这个需求。

    copy npx command.jpg

    一个 npx command 类似于下面这样,记录了当前压缩算法和详细压缩配置

    npx @squoosh/cli --mozjpeg \
    '{"quality":40,"baseline":false,"arithmetic":false,"progressive":true,"optimize_coding":true,"smoothing":0,"color_space":3,"quant_table":3,"trellis_multipass":false,"trellis_opt_zero":false,"trellis_opt_table":false,"trellis_loops":1,"auto_subsample":true,"chroma_subsample":2,"separate_chroma_quality":false,"chroma_quality":75}'
    

    一个重要的插曲,解决报错 TypeError: Cannot read properties of undefined (reading 'writeText')

    这是 Chrome 限制了非安全网站的 API 使用,在非安全网站上 block 了 navigator.clipboard 的 api 使用权限,所以无法拷贝 npx 命令出来。下面解决这个问题。

    open chrome ,type chrome://flags/ in address bar, then find item Insecure origins treated as secure, type http://10.10.10.5:7701 then enable it and relaunch your chrome.

    Chrome 在此处认为的安全的网站

    • 必须 https
    • 或 localhost
    • 或 127.0.0.1

    所以我们有必要加个白名单,这样好操作。

    insecure origins.jpg

    ps: http://10.10.10.5:7701 是我 squoosh 的运行环境地址。如果有多个地址需要设“白名单”,使用英文逗号隔开它们即可。

    /home/dk/squooshfiles 创建目录 0805,然后把要批量压缩的照片拷贝进去,接下来就是批量压缩了。

    使用 squoosh-cli 替换掉 npx 拷贝出来的命令中的 npx @squoosh/cli,然后执行

    # squoosh-cli --mozjpeg \ 
    '{"quality":40,"baseline":false,"arithmetic":false,"progressive":true,"optimize_coding":true,"smoothing":0,"color_space":3,"quant_table":3,"trellis_multipass":false,"trellis_opt_zero":false,"trellis_opt_table":false,"trellis_loops":1,"auto_subsample":true,"chroma_subsample":2,"separate_chroma_quality":false,"chroma_quality":75}' \
    -d output1 \
    -s dk-compressed \
    *.jpeg
    

    解释

    • mozjpeg 是最常用的压缩算法了,综合来说最推荐。(具体各种算法还没有研究
    • quality 就是压缩质量了,在网页端可以直接预览压缩后的效果
    • -d 设置输出目录
    • -s 设置一个输出的文件名后缀,默认是空字符串
    • 最后的 files ,可以使用简单的通配符,比如 *.jpeg 只压缩当前目录下的所有 jpeg 扩展名图片

    批量压缩成功。

    squoosh results.jpg

    在 win 本地通过 samba4 挂载后的预览,非常方便。

    overview.jpg

    把图片从 output1 路径中拷贝出来一份,对比原有图片和有损压缩后的效果,非常赞

    最后感谢 squoosh 项目,写博客压缩图片利器,完全免费开源,非常推荐各位博主使用。

    20 条回复    2023-08-08 10:51:52 +08:00
    houshuu
        1
    houshuu  
       199 天前 via iPhone
    习惯 ppduck 了,免费版本常规用用也足够了
    790002517zzy
        2
    790002517zzy  
       199 天前 via Android
    你这个 docker 怎么用
    BaseException
        3
    BaseException  
    OP
       199 天前
    @houshuu #1 我是最近出去旅行了,写了两篇文章,贴图 100 张,所以感觉还是需要这个东西。
    BaseException
        4
    BaseException  
    OP
       199 天前
    @790002517zzy #2
    直接 docker run

    ```
    docker run -d --name squoosh \
    --restart unless-stopped \
    -p 7701:8080 \
    -v /home/dk/squooshfiles:/app/squooshfiles \
    dko0/squoosh:1.12.0
    ```

    然后进入容器安装 `npm i -g @squoosh/cli` 默认 latest 版本 然后就能用了。

    docker 的目的主要是为了环境容易搭建,另外不破坏宿主环境
    iyour
        5
    iyour  
       199 天前   ❤️ 1
    squoosh 确实很好用,我也基于 squoosh 写了一个在线图片压缩工具 https://www.photofun.cn/compress ,并且支持批量压缩
    BaseException
        6
    BaseException  
    OP
       199 天前 via iPhone
    @iyour #5 很赞 前端开发真的好酷
    ab
        7
    ab  
       199 天前
    本地压缩的话,mac 有个 sips ,一行解君愁

    sips -s formatOptions high path/*.jpg
    BaseException
        8
    BaseException  
    OP
       199 天前
    @ab #7 之前搜到过这个,也能用。squoosh 可调整项更多,适合高阶用户吧。像是 chh 论坛,只能上传 500KB 以内的图片,如果用这个发现压缩后还是很大就比较没辙了吧,squoosh 可以继续降低质量或者其他可调整项,甚至其他压缩算法
    Aixtuz
        9
    Aixtuz  
       198 天前
    之前也有这个需求,于是用 raycast 存了这么一段 snippets:
    ```
    npx @squoosh/cli --mozjpeg '{"quality":80,"baseline":false,"arithmetic":false,"progressive":true,"optimize_coding":true,"smoothing":0,"color_space":3,"quant_table":3,"trellis_multipass":false,"trellis_opt_zero":false,"trellis_opt_table":false,"trellis_loops":1,"auto_subsample":true,"chroma_subsample":2,"separate_chroma_quality":false,"chroma_quality":75}' * -d ./out
    ```
    ye4241
        10
    ye4241  
       198 天前
    Windows 上面我一般用 pingo ,压缩率还是很高的,在线的 tinypng ,写个接口调用网页版的无限压缩。
    https://css-ig.net/pingo
    https://tinypng.com/

    以上两个都比 mozjpeg 强大一些,个人感觉,无论在速度还是尺寸上。
    BaseException
        11
    BaseException  
    OP
       198 天前
    @Aixtuz #9 raycast 是那个工作流提升软件吧,这个看起来似乎就是个 linux command alias
    BaseException
        12
    BaseException  
    OP
       198 天前
    @ye4241 #10 感谢推荐。之前也用 tinypng 来着,不过免费版是有限制的吧? tinypng 的压缩效果的确也不错,好像不开源,不知道实现方法
    ye4241
        13
    ye4241  
       198 天前
    @BaseException #12 我用的做了个网页版的逆向接口,一天能压缩个很多张,对于普通使用来说,足够了,而且他们的 API 接口,也有免费额度。
    BaseException
        14
    BaseException  
    OP
       198 天前
    @ye4241 #13 是的,有免费额度,我也用过。你推荐的 pingo 还有 benchmark 有点意思。
    bertonzh
        15
    bertonzh  
       197 天前
    好奇为啥不直接使用 mozjpeg 命令行?感觉用 docker 做这个,挺重的。
    另外可以试试我的这个 https://github.com/meowtec/Imagine ,只不过压缩器和配置没有 squoosh 丰富。
    BaseException
        16
    BaseException  
    OP
       197 天前 via iPhone
    @bertonzh #15 docker 的目的是在内网或者自己的服务器上部署一个 squoosh ,不喜欢用公网服务的人应该能理解吧,比如在 http://192.168.2.100:7701 上使用 squoosh web ui
    BaseException
        17
    BaseException  
    OP
       197 天前
    @bertonzh #15 你的这个前阵子有用过,蛮好的,感谢分享
    ma5onxu
        18
    ma5onxu  
       197 天前
    以前 node 安装 squoosh cli 可以自带批量压缩,后来报错直接不维护了。 😭,原来 google 这么大公司也会不维护这么好的东西。
    bertonzh
        19
    bertonzh  
       197 天前
    @BaseException 了解了,我还以为完全本地使用
    ma5onxu
        20
    ma5onxu  
       197 天前
    @bertonzh #15 感谢大佬,挺好用的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5941 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 06:05 · PVG 14:05 · LAX 22:05 · JFK 01:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.