我有几千个要处理的图像,因此每毫秒都很重要。每张图片的大小约为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&#s; 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"
答案 0 :(得分: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
答案 1 :(得分:3)
我创建了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 的速率。
答案 2 :(得分: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 \)"..
我永远不会记得它是在文件名之前还是之后
答案 3 :(得分:2)
在Magick Persistent Registry(.mpc
)上尝试Magick持久缓存图像文件格式(.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
答案 4 :(得分:0)
ImageMagick有一个名为-thumbnail <geometry>
的特殊调整大小运算符变体,用于将非常大的图像转换为小缩略图。在内部,它使用
-sample
将图像缩小到最终高度的5倍,如果缩略图比原始图像小得多,则比-resize
快得多。 由于此运算符使用简化的滤镜集,因此忽略-filter
运算符! -strip
从图片中删除缩略图通常不需要的所有配置文件。这也进一步减小了生成的图像文件的大小。-resize
最终创建所需的尺寸和比率当谈到从JPEG图像创建缩略图时,可以使用特殊的JPEG缩放加载选项-define jpeg:size=<size>
,如user894763所述。 请注意,必须在convert
之后立即指定此选项,例如:
convert -define jpeg:size=<size> input-image.jpg ...
无论如何,-thumbnail
运算符可以另外指定,因为它会从缩略图图像中删除所有配置文件,从而减小文件大小。
答案 5 :(得分: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
时间:0m0.952s
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,因此每次编写和读取中间图像时都会失去更多的视觉质量。因此,一条长命令行的质量也应该更好。