我制作了一些图像并进行了一些测试,以便您可以看到各种技术对性能的影响。
我使图像包含随机的、难以压缩的数据,其尺寸和文件大小与您的匹配,即
convert -size 8000x6000 xc:gray +noise random -quality 35 image.jpg
然后,ls 像这样给出 13MB:
-rw-r--r-- 1 mark staff 13M 23 Aug 17:55 image.jpg
我制作了 128 个这样的随机图像,因为它们可以很好地被我机器上的 8 个 CPU 内核整除 - 稍后请参阅并行测试。
现在是方法...
方法一
这是一种幼稚的方法 - 您只需一个接一个地创建您要求的所有文件。
#!/bin/bash
for f in image*jpg; do
for w in 3000 2000 1000 500 250 100; do
convert $f -resize ${w}x res_${f}_${w}.jpg
done
done
时间:26 分 46 秒
方法二
这里我们只读取每个图像一次,但从一个输入图像生成所有输出大小,并且速度要快得多。
#!/bin/bash
for f in image*jpg; do
convert $f -resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
done
时间:6 分 17 秒
方法3
在这里,我们预先建议 ImageMagick,我们将需要的最大图像只有 3000x2250 像素,因此它可以使用更少的内存并读取更少的 DCT 级别并执行更少的 I/O。这称为“加载时收缩”。
#!/bin/bash
for f in image*jpg; do
convert -define jpeg:size=3000x2250 $f \
-resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
done
时间:3 分 37 秒
顺便说一句,当您预先告诉 ImageMagick 您需要多大的图像时,为了演示所需的时间、I/O 和内存减少,比较这两个命令,都读取您的一个8000x6000、13MB 的图像,并且都生成相同的缩略图:
/usr/bin/time -l convert image.jpg -resize 500x result.jpg 2>&1 | egrep "resident|real"
1.92 real 1.77 user 0.14 sys
415727616 maximum resident set size
即415 MB 和 2 秒
/usr/bin/time -l convert -define jpeg:size=500x500 image.jpg -resize 500x result.jpg 2>&1 | egrep "resident|real"
0.24 real 0.23 user 0.01 sys
23592960 maximum resident set size
即23 MB 和 0.2 秒 - 输出图像具有相同的内容和质量。
方法四
在这里,我们全力以赴并使用 GNU Parallel 以及所有上述技术来让您的 CPU、风扇和功耗疯狂!!!
#!/bin/bash
for f in image*jpg; do
cat<<EOF
convert -define jpeg:size=3000x2250 $f \
-resize 3000x -write res_${f}_3000.jpg \
-resize 2000x -write res_${f}_2000.jpg \
-resize 1000x -write res_${f}_1000.jpg \
-resize 500x -write res_${f}_500.jpg \
-resize 250x -write res_${f}_250.jpg \
-resize 100x res_${f}_100.jpg
EOF
done | parallel
时间:56 秒
总之,我们可以将处理时间从 27 分钟减少到 56 秒,方法是避免不必要地读取图像并在每个输入中执行尽可能多的输出,方法是预先告诉 ImageMagick 它需要读取多少输入图像和通过使用 GNU Parallel 让所有可爱的 CPU 内核保持忙碌。 HTH。