ImageMagick单转换命令性能

问题描述 投票:3回答:6

我有几千个图像要处理,所以每毫秒计数。每张图片的大小约为2-3Mb。

源文件送到转换器:image.jpg

要从源生成的文件:

orig_image.jpg      // original image
1024x768_image.jpg  // large image
250x250_image.jpg   // thumbnail 1
174x174_image.jpg   // thumbnail 2

在浏览imagemagick转换性能的不同主题时,我感觉单个命令应该比每个图像大小的单个转换更快。此外,还提到了内存利用率作为性能提升。 (ImageMagick batch resizing performance

多个命令转换(每个命令在循环中通过php的exec()运行):

convert "image.jpg" \
    -coalesce -resize "1024x768>" +repage "1024x768_image.jpg"

convert "1024x768_image.jpg" \
    -coalesce \
    -resize "250x250>" \
    +repage \
    -gravity center \
    -extent "250x250" "250x250_image.jpg"

convert "1024x768_image.jpg" \
    -coalesce \
    -resize "174x174>" \
    +repage \
    -gravity center \
    -extent "174x174" "174x174_image.jpg"

mv image.jpg orig_image.jpg

包含ImageMagicks mpr的单一命令转换:

convert "image.jpg" -quality 85 -colorspace rgb -coalesce \
    -resize "1024x768>" \'
    -write "1024x768_image.jpg" \
    -write mpr:myoriginal +delete \
    mpr:myoriginal -coalesce \
    -resize "250x250>" \
    -gravity center \
    -extent "250x250" \
    -write "250x250_image.jpg" +delete \
    mpr:myoriginal -coalesce \'
    -resize "174x174>" \
    -gravity center \
    -extent "174x174" \
    -write "174x174_image.jpg"

性能测试后,结果有些出乎意料。循环中的单个命令转换在62秒内完成,而多个命令转换仅在16秒内执行?

# convert -version
Version: ImageMagick 7.0.2-1 Q8 i686 2017-02-03 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2016 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP
Delegates (built-in): bzlib freetype jng jpeg lzma png tiff wmf xml zlib

还安装了libjpeg-turbo jpg处理库,但我不知道(不知道如何检查)如果ImageMagic正在使用它或旧的libjpeg。

任何想法如何加快图像转换过程?

编辑:不知道如何在stackoverflow上正确格式化它,但我只是注意到单行命令有一个参数“-colorspace rgb”并且多行命令没有实际导致如此奇怪的结果,其中多个命令被更快地处理。

删除了“-colorspace rgb”参数,之后MPR转换版本运行最佳,并提供了额外的性能提升。

总而言之,我最终使用了这个命令:

// MPR
convert "orig_image.jpg" -quality 80 -coalesce \
    -resize "1024x768>" \
    -write 1024x768_image.jpg \
    -write mpr:myoriginal +delete \
    mpr:myoriginal -resize "250x250>" \
    +repage -gravity center -extent "250x250" \
    -write "250x250_image.jpg" \
    -write mpr:myoriginal +delete \
    mpr:myoriginal -coalesce -resize "174x174>" \
    +repage -gravity center -extent "174x174" \
    -write "174x174_image.jpg"
php imagemagick imagemagick-convert
6个回答
3
投票

你没有使用jpeg收缩负载,这将提供一个简单的加速。

jpeg库有一个简洁的功能,它可以让你以全分辨率,1 / 2,1 / 4或1/8进行解压缩。由于jpg在内部工作的方式,1/8分辨率特别快。

要在convert中利用它,你需要提示你需要一个特定大小的图像的jpeg加载器。为避免混叠,您应该要求至少比目标尺寸大200%的图像。

在这台机器上,我看到:

$ vipsheader image.jpg 
image.jpg: 5112x3470 uchar, 3 bands, srgb, jpegload
$ time convert image.jpg -resize 1024x768 1024x768_image.jpg
real    0m0.405s
user    0m1.896s
sys 0m0.068s

如果我设置了收缩负载提示,它的速度提高了约2倍:

$ time convert -define jpeg:size=2048x1536 image.jpg -resize 1024x768 1024x768_image.jpg
real    0m0.195s
user    0m0.604s
sys 0m0.016s

对于非常大的jpg文件,你会看到一个惊人的加速。

你也可以考虑另一个缩略图。例如,vipsthumbnail再次快一点:

$ time vipsthumbnail image.jpg -s 1024x768 -o 1024x768_image.jpg
real    0m0.111s
user    0m0.132s
sys 0m0.024s

虽然实时时间仅下降了2倍,但用户时间却下降了5倍左右。这使得与gnu并行运行很有用。例如:

parallel vipsthumbnail image.jpg -s {} -o {}_image.jpg ::: \
    1024x768 250x250 174x174

3
投票

埃里克和约翰的建议有很多智慧,可以和我的建议混在一起 - 这就是使用GNU Parallel。当你有成千上万的图像时,它真的会计算在内。

我创建了100个图像(实际上使用GNU Parallel,但这不是重点),通过image-0.jpg称为image-99.jpg。然后,我做了一个简单的调整大小操作,只是为了展示如何做到这一点,而不是太多挂在ImageMagick方面。首先,我按顺序执行,花了48秒来调整100张图像,然后我使用GNU Parallel做了完全相同的事情,并在10秒内完成 - 因此可以节省大量时间。

#!/bin/bash
# Create a function used by both sequential and parallel versions - it's only fair
doit(){
   echo Converting $1 to $2
   convert -define jpeg:size=2048x1536 "$1" -resize 1024x768 "$2"
}
export -f doit

# First do them all sequentially - 48 seconds on iMac
time for img in image*.jpg; do
   doit $img "seq-$img"
done

# Now do them in parallel - 10 seconds on iMac
time parallel doit {} "par-{}" ::: image*.jpg

只是为了踢 - 观看CPU测量仪(在电影的右上角)和文件在电影的最后1/6中弹出GNU Parallel的速率。

enter image description here


2
投票

这很有趣,因为我前一段时间做了一些转换,发现mpr也慢了。无论如何试试这个:

$cmd = " convert "image.jpg" -colorspace rgb -coalesce \( -clone 0 -resize 1024x768> -write 1024x768_image.jpg +delete \)".
" \( -clone 0 -resize 250x250> -gravity center -extent 250x250 -write 250_wide.jpg +delete \) ".
" -resize 174x174> -gravity center -extent 174x174  null: ";
exec("convert $cmd 174x174_image.jpg ");

我注意到你没有背景颜色。

您还可以在循环方法中添加-define,并在此列表中查看:https://www.imagemagick.org/script/command-line-options.php#define jpeg:size = geometry仅读取创建图像所需的数据量而不读取整个图像。您也可以将它添加到第一行。 -quality用于输出,并且在您放置它时不起作用。

 $cmd = " convert "image.jpg" jpeg:size=1024x768 -colorspace rgb -coalesce \( -clone 0 -resize 1024x768> -write 1024x768_image.jpg +delete \)"..

我永远不会记得它是在文件名之前还是之后


2
投票

在Magick Persistent Registry(.mpc)上尝试Magick Persistent Cache图像文件格式(.mpr)。

convert "image.jpg" -quality 85 -colorspace rgb myoriginal.mpc
convert myoriginal.mpc \
    -resize "1024x768>" \
    -write "1024x768_image.jpg" \
    -resize "250x250>" \
    -gravity center \
    -extent "250x250" \
    -write "250x250_image.jpg"  \
    -resize "174x174>" \
    -gravity center \
    -extent "174x174" \
    "174x174_image.jpg"

当使用1.8mb jpeg进行测试时,会导致以下时间。

real    0m0.051s
user    0m0.133s
sys     0m0.013s

确实,这将需要两个命令(尽管可以简化为-write ... +delete),但在将.mpc加载回图像堆栈后,I / O成本非常低。

要么

你可以跳过.mpc和...

convert "image.jpg" -quality 85 -colorspace rgb \
    -resize "1024x768>" \
    -write "1024x768_image.jpg" \
    -resize "250x250>" \
    -gravity center \
    -extent "250x250" \
    -write "250x250_image.jpg"  \
    -resize "174x174>" \
    -gravity center \
    -extent "174x174" \
    "174x174_image.jpg"

结果......

real    0m0.061s
user    0m0.163s
sys     0m0.012s

0
投票

ImageMagick有一个名为-thumbnail <geometry>的特殊调整大小运算符变体,用于将非常大的图像转换为小缩略图。它在内部使用

  1. -sample将图像缩小到最终高度的5倍,如果缩略图比原始图像小得多,则比-resize快得多。因为此运算符使用减少的滤波器集,所以忽略-filter运算符!
  2. -strip删除图像中通常不需要缩略图的所有配置文件。这还进一步减小了生成的图像文件的大小。
  3. -resize最终创建所需的大小和比例

在从JPEG图像创建缩略图时,可以使用特殊的JPEG缩放加载选项-define jpeg:size=<size>,如user894763所述。请注意,必须在convert之后立即指定此选项,例如:

convert -define jpeg:size=<size> input-image.jpg ...

无论如何,-thumbnail运算符可以另外指定,因为它从缩略图图像中删除所有配置文件,从而减小文件大小。

详细信息可以在ImageMagick usage documentation找到。


0
投票

我在ImageMagick 6.9.10.0 Q16 Mac OSX中使用一个命令行大约一半的时间从3 MB输入JPG图像开始。

list="image.jpg"
time for img in $list; do
convert "image.jpg" \
-coalesce -resize "1024x768>" +repage "1024x768_image.jpg"

convert "1024x768_image.jpg" \
-coalesce \
-resize "250x250>" \
+repage \
-gravity center \
-extent "250x250" "250x250_image.jpg"

convert "1024x768_image.jpg" \
-coalesce \
-resize "174x174>" \
+repage \
-gravity center \
-extent "174x174" "174x174_image.jpg"
done

时间:0分90秒

time convert "image.jpg" \
-resize "1024x768>" \
+write "1024x768_image.jpg" \
-resize "250x250>" \
-gravity center \
-extent "250x250" \
+write "250x250_image.jpg"  \
-resize "174x174>" \
-gravity center \
-extent "174x174" \
"174x174_image.jpg"

时间:0m0.478s

由于JPG不支持虚拟画布,因此不需要在多个命令中合并。因此删除它会将乘法命令行时间减少到0m0.738s

由于您必须编写和读取中间图像,因此多个命令应该更长。由于您的中间图像是JPG,因此每次编写和读取中间图像时都会失去更多的视觉质量。因此,一条长命令行的质量也应该更好。

© www.soinside.com 2019 - 2024. All rights reserved.