Reputation: 1151
I have a few million images stored as jpgs. I'd like to reduce the size of each jpg by 80%. Here's a bash loop that I'm currently using (I'm on MacOS):
for i in *jpg; do convert "$i" -quality 80% "${i%.jpg}.jpg"; done;
The above line converts the images sequentially. Is there a way to parallelize and thus speed up this conversion? I don't need to use bash, just want to find the fastest way to make the conversion.
Upvotes: 1
Views: 382
Reputation: 33748
Using GNU Parallel it looks like this:
parallel convert {} -quality 80% {.}_80.jpg ::: *jpg
If the million jpgs are in the same dir, the above line will be too long. Then try:
printf '%s\0' *.jpg | parallel -0 convert {} -quality 80% {.}_80.jpg
Upvotes: 0
Reputation: 88929
Parallelise the execution of convert
with GNU xargs. This will run 10 convert
processes simultaneously and restart more processes if less than 10 are running simultaneously until 10 are running simultaneously again.
printf "%s\n" *.jpg | xargs -P 10 -I {} convert {} -quality 80% {}
xargs
replaces all {}
in convert
command with the file name that comes from stdin.
I assume that your file names do not contain a line break. The original files are overwritten.
Upvotes: 0
Reputation: 2962
Using Python you can do it this way:
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")))
Given that your images are in images/*.jpg
.
Upvotes: 1