【问题标题】:How to reduce file size of millions of images?如何减少数百万张图片的文件大小?
【发布时间】:2021-12-25 12:37:36
【问题描述】:

我有几百万张图片以 jpg 格式存储。我想将每个 jpg 的大小减小 80%。这是我目前正在使用的 bash 循环(我在 MacOS 上):

for i in *jpg; do convert "$i" -quality 80% "${i%.jpg}.jpg"; done; 

以上行顺序转换图像。有没有办法并行化从而加快这种转换?我不需要使用 bash,只想找到最快的方式进行转换。

【问题讨论】:

  • multiprocessing。这个想法是在多进程之间共享工作。每个人都得到一个文件名列表并并行处理它们。您将能够从 python 代码调用convert
  • @balderman 是否有提供类似于convert 的功能的python 包?
  • 看看PIL
  • 我想我会尝试使用 GNU 并行来编写一个简单的 shell 脚本。

标签: python bash image jpeg


【解决方案1】:

使用 Python 你可以这样做:

import glob
import shlex
import subprocess
from tqdm.contrib.concurrent import thread_map

def reduce_file(filepath):
    output = f"{filepath}_reduced.jpg"
    cmd = f"convert {filepath} -quality 80% {output}"
    subprocess.run(shlex.split(cmd))

list(thread_map(reduce_file, glob.glob("./images/*.jpg")))

鉴于您的图片位于images/*.jpg

【讨论】:

    【解决方案2】:

    使用 GNU xargs 并行执行 convert。这将同时运行 10 个 convert 进程,如果同时运行的进程少于 10 个,则重新启动更多进程,直到 10 个进程再次同时运行。

    printf "%s\n" *.jpg | xargs -P 10 -I {} convert {} -quality 80% {}
    

    xargsconvert 命令中的所有{} 替换为来自标准输入的文件名。

    我假设您的文件名不包含换行符。原始文件被覆盖。

    【讨论】:

      【解决方案3】:

      使用 GNU Parallel 它看起来像这样:

      parallel convert {} -quality 80% {.}_80.jpg ::: *jpg 
      

      如果百万个jpg在同一个目录下,上面的行会太长。然后试试:

      printf '%s\0' *.jpg | parallel -0 convert {} -quality 80% {.}_80.jpg
      

      【讨论】:

        猜你喜欢
        • 2011-02-03
        • 2023-04-08
        • 2012-03-31
        • 1970-01-01
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-12
        相关资源
        最近更新 更多