12

我希望在 Python 中使用 ImageMagick 的转换实用程序有效地生成各种大小的缩略图。我的一些图像文件非常大(~15MB JPG)。

我可以做到的一种方法是获取全尺寸图像,并从全尺寸图像生成各种缩略图,如下所示:

convert sample_image.jpg -resize 1024x768  sample_image-1024x768.jpg
convert sample_image.jpg -resize 800x600   sample_image-800x600.jpg
convert sample_image.jpg -resize 400x300   sample_image-400x300.jpg
convert sample_image.jpg -resize 200x150   sample_image-200x150.jpg

但另一种方法是相互调整图像的大小:

convert sample_image.jpg           -resize 1024x768  sample_image-1024x768.jpg
convert sample_image-1024x768.jpg  -resize 800x600   sample_image-800x600.jpg
convert sample_image-800x600.jpg   -resize 400x300   sample_image-400x300.jpg
convert sample_image-400x300.jpg   -resize 200x150   sample_image-200x150.jpg

这样做有什么缺点,或者可能有更好的方法吗?看起来这样会更有效率。

作为推论,是否有任何标志或“技巧”转换用于加速该过程?

4

5 回答 5

18

ImageMagick 有一些技巧可以帮助您在想要处理大图像以及想要从相同的原始图像创建不同的输出时优化速度:

  1. 利用 ImageMagick 的mpr:{name}功能,它可以将输入图像临时保存到一个命名的内存程序寄存器中,以后(在处理时)从中读取数据的速度比从硬盘读取的快得多。

  2. 在一个进程中执行所有调整大小操作,写出您需要的不同输出大小。

更好的消息是您可以将这两者组合成一个命令。

因此,您不需要运行多个进程以及它们的所有上下文切换开销——一次完成所有操作。

以下示例还从原始图像中裁剪了两个单独的区域,并从中创建了重新调整大小的缩略图,只是为了显示 IM 可以在一个命令行中执行多少不同的操作。当然,它还会输出您要求的尺寸。(当然,您需要一个非常大尺寸的输入图像才能使裁剪参数起作用)。

convert                           \
  huge-original.jpg               \
 -quality 80                      \
 -colorspace rgb                  \
 +profile '*'                     \
 -filter Lanczos                  \
 -write mpr:copy-of-huge-original \
 +delete                          \
  mpr:copy-of-huge-original -crop '3000x2000+0+480'   -resize '200x125!>' -write thumb1-extract.jpg +delete \
  mpr:copy-of-huge-original -crop '2000x1500+280+220' -resize '75x75!>'   -write thumb2-extract.jpg +delete \
  mpr:copy-of-huge-original -resize '1024x768'  -write sample-1024x768.jpg +delete \
  mpr:copy-of-huge-original -resize '800x600'   -write sample-800x600.jpg  +delete \
  mpr:copy-of-huge-original -resize '400x300'   -write sample-400x300.jpg  +delete \
  mpr:copy-of-huge-original -resize '200x150'   -write sample-200x150.jpg  +delete \
  mpr:copy-of-huge-original -resize '163x163!>' -write sample-163x163.jpg

更新

我现在才看到@JonathanOng 提出的问题:如何将输出流式传输到<stdout>

假设,您希望标准输出的格式也是 JPEG,您可以试试这个:

convert                           \
  huge-original.jpg               \
 -quality 80                      \
 -colorspace rgb                  \
 +profile '*'                     \
 -filter Lanczos                  \
 +write mpr:copy-of-huge-original \
  mpr:copy-of-huge-original -crop '3000x2000+0+480'   -resize '200x125!>' +write thumb1-extract.jpg \
  mpr:copy-of-huge-original -crop '2000x1500+280+220' -resize '75x75!>'   +write thumb2-extract.jpg \
  mpr:copy-of-huge-original -resize '1024x768'  +write jpeg:- \
  mpr:copy-of-huge-original -resize '800x600'   +write jpeg:- \
  mpr:copy-of-huge-original -resize '400x300'   +write jpeg:- \
  mpr:copy-of-huge-original -resize '200x150'   +write jpeg:- \
  mpr:copy-of-huge-original -resize '163x163!>' +write jpeg:-

这样每个变体都会进入标准输出。那么,如何处理这些连续图像流取决于您...

请注意-write filename +delete您可以使用+write filename. 这相当于相同的效果。

于 2012-10-02T10:44:40.633 回答
1

我尝试vipsthumbnail针对@KurtPfeifle 的出色回答进行计时。我使用 10k x 10k 像素的 RGB JPG 图像(大约 15MB)运行它:

convert                           \
  /data/john/pics/wtc.jpg         \
 -quality 80                      \
 -colorspace rgb                  \
 +profile '*'                     \
 -filter Lanczos                  \
 -write mpr:copy-of-huge-original \
 +delete                          \
  mpr:copy-of-huge-original -resize '1024x768'  -write sample-1024x768.jpg +delete \
  mpr:copy-of-huge-original -resize '800x600'   -write sample-800x600.jpg  +delete \
  mpr:copy-of-huge-original -resize '400x300'   -write sample-400x300.jpg  +delete \
  mpr:copy-of-huge-original -resize '200x150'   -write sample-200x150.jpg  +delete \
  mpr:copy-of-huge-original -resize '163x163!>' -write sample-163x163.jpg  x.jpg

我发现我x.jpg最后需要额外的,我不知道为什么。在这台机器上(E5-1650 3.2 GHz,IM 6.8.9-9)我看到:

$ time ./m.sh 
real    0m6.560s
user    0m31.908s
sys     0m0.264s
peak RES 711MB

这(我认为)相当于vipsthumbnail

img=/data/john/pics/wtc.jpg
icc=/usr/share/color/argyll/ref/sRGB.icm

for size in 1024x768 800x600 400x300 200x150 163x163; do
  vipsthumbnail $img --size $size --eprofile $icc -o vips-sample-$size.jpg[Q=80]
done

vipsthumbnail默认为 Lanczos3。用 vips-8.4.4 计时我看到:

$ time ./n.sh
real    0m2.376s
user    0m2.412s
sys     0m0.108s
peak RES 70MB

所以一个有用的加速,和内存使用的大幅下降。

因为内存使用率很低,所以您可以vipsthumbnail并行运行许多而不杀死您的服务器。如果我将脚本更改为:

img=/data/john/pics/wtc.jpg
icc=/usr/share/color/argyll/ref/sRGB.icm

parallel vipsthumbnail $img \
  --size {} --eprofile $icc -o vips-sample-{}.jpg[Q=80] ::: \
  1024x768 800x600 400x300 200x150 163x163

我现在看到:

$ time ./n.sh 
real    0m0.593s
user    0m1.960s
sys     0m0.100s
peak RES 280MB

比 ImageMagick 快 10 倍以上。

于 2017-01-16T14:40:13.640 回答
0

在我看来,经过测试,将 1024x768 的大小调整为 800x600 对重新缩放算法不利。由于整数 (2) 的倍数,下一次调整大小更容易。

所以,出于质量原因,我个人认为,这更好:

convert sample_image.jpg -resize 1024x768  sample_image-1024x768.jpg
convert sample_image.jpg -resize 800x600   sample_image-800x600.jpg
convert sample_image-800x600.jpg   -resize 400x300   sample_image-400x300.jpg
convert sample_image-400x300.jpg   -resize 200x150   sample_image-200x150.jpg
于 2012-08-30T22:23:46.513 回答
0

15MB JPG 真的很大。我会首先使用最快的“ -sample ”参数将其调整为合理的大小(比如 2500x2500),然后将这个较小的图像调整为不同的缩略图。

您可以根据图像大小做出明智的决定,并选择正确的调整大小方式。

我建议关注缩略图质量而不是转换速度,因此请查看不同的过滤器 ( -filter )、锐化 ( -unsharp ) 和推荐的下采样方法

于 2012-10-02T09:38:47.600 回答
0

我正在缩略图〜50MB JPG文件。产生最大差异的一个选项(约 5 倍加速)是在输入文件名之前的“-define jpeg:size 128x128”。这里给出的例子:

http://www.imagemagick.org/Usage/formats/#jpg_read

...产生了巨大的变化:

convert -define jpeg:size=128x128 jpeg_large.jpg -thumbnail 64x64  jpeg_thumbnail.jpg

-define jpeg:size 允许 ImageMagick 仅从磁盘读取所需的数据,这大大减少了非常大的图像的加载时间。

正如链接页面所建议的那样,使用两倍于最终缩略图大小的 jpeg:size= 以避免混叠。

-thumbnail 选项,在此处描述:

http://www.imagemagick.org/Usage/resize/#thumbnail

...对图像进行采样和剥离,进一步加快处理速度。

于 2017-01-12T17:36:43.430 回答