[英]Fastest way to create multiple thumbnails from a single large image in Python
我有一个大图像库(8000x6000px~13mb),我想生成多个尺寸较小的缩略图,宽度分别为3000px,2000px,1000px,500px,250px和100px。
源图像存储在平面文件中,生成的缩略图也将存储在平面文件中。
我一直在考虑在Python中执行此操作的最佳方法,这些都是立即浮现在脑海中的潜在问题:
优化缩略图生成时还有其他事项要记住吗? 入门时非常感谢示例代码。 谢谢。
我做了一些图像并做了一些测试,这样你就可以看到各种技术对性能的影响。
我使图像包含尺寸和文件大小的随机,难以压缩的数据以匹配您的图像,即
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内核整除 - 稍后会看到并行测试。
现在的方法......
方法1
这是天真的方法 - 你只需要一个接一个地创建你要求的所有文件。
#!/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秒
方法2
这里我们只读取一次图像,但是从一个输入图像生成所有输出尺寸,并且速度要快得多。
#!/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秒
顺便说一句,为了展示缩短的时间,I / O和内存需要预先告诉ImageMagick你需要预先设置一个图像,比较这两个命令,两者都读取你的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秒 - 输出图像具有相同的内容和质量。
方法4
在这里我们全力以赴并使用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秒
总之,我们可以通过预先告诉ImageMagick需要读取多少输入图像并使用GNU来避免不必要地读取图像并尽可能多地输入每个输入,从而将处理时间从27分钟缩短到56秒并行保持所有可爱的CPU内核忙碌。 HTH。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.