如何减少数百万图像的文件大小?
How to reduce file size of millions of images?
我有几百万张以 jpg 格式存储的图像。我想将每个 jpg 的大小减少 80%。这是我目前正在使用的 bash 循环(我在 MacOS 上):
for i in *jpg; do convert "$i" -quality 80% "${i%.jpg}.jpg"; done;
上面一行按顺序转换图像。有没有办法并行化从而加速这种转换?我不需要使用 bash,只是想找到最快的转换方式。
使用 GNU xargs 并行执行 convert
。这将同时 运行 10 convert
个进程并重新启动更多进程,如果少于 10 个进程同时 运行ning 直到 10 个进程再次同时 运行ning。
printf "%s\n" *.jpg | xargs -P 10 -I {} convert {} -quality 80% {}
xargs
将 convert
命令中的所有 {}
替换为来自标准输入的文件名。
我假设您的文件名不包含换行符。原来的文件被覆盖了。
使用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
。
使用 GNU Parallel 看起来像这样:
parallel convert {} -quality 80% {.}_80.jpg ::: *jpg
如果百万个 jpg 在同一个目录中,上面的行会太长。然后尝试:
printf '%s[=11=]' *.jpg | parallel -0 convert {} -quality 80% {.}_80.jpg
我有几百万张以 jpg 格式存储的图像。我想将每个 jpg 的大小减少 80%。这是我目前正在使用的 bash 循环(我在 MacOS 上):
for i in *jpg; do convert "$i" -quality 80% "${i%.jpg}.jpg"; done;
上面一行按顺序转换图像。有没有办法并行化从而加速这种转换?我不需要使用 bash,只是想找到最快的转换方式。
使用 GNU xargs 并行执行 convert
。这将同时 运行 10 convert
个进程并重新启动更多进程,如果少于 10 个进程同时 运行ning 直到 10 个进程再次同时 运行ning。
printf "%s\n" *.jpg | xargs -P 10 -I {} convert {} -quality 80% {}
xargs
将 convert
命令中的所有 {}
替换为来自标准输入的文件名。
我假设您的文件名不包含换行符。原来的文件被覆盖了。
使用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
。
使用 GNU Parallel 看起来像这样:
parallel convert {} -quality 80% {.}_80.jpg ::: *jpg
如果百万个 jpg 在同一个目录中,上面的行会太长。然后尝试:
printf '%s[=11=]' *.jpg | parallel -0 convert {} -quality 80% {.}_80.jpg