如何加快复杂的图像处理速度?

时间:2015-02-24 19:51:29

标签: php image imagemagick converter imagemagick-convert

每位用户都可以上传100张TIFF(黑白)图片。

该流程需要:

  1. tif转换为jpg

  2. 将图片大小调整为xx。

  3. 将图像裁剪为200px。

  4. 添加文字水印。

  5. 这是我的PHP代码:

    move_uploaded_file($image_temp,$destination_folder.$image_name);
    
    $image_name_only = strtolower($image_info["filename"]);
    
    $name=$destination_folder.$image_name_only.".jpg";
    $thumb=$destination_folder."thumb_".$image_name_only.".jpg";
    $exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$destination_folder.$image_name. ' '.$name.' 2>&1';
    exec($exec, $exec_output, $exec_retval);                
    
    $exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -resize 1024x  '.$name;
    exec($exec, $exec_output, $exec_retval);
    
    $exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. ' -thumbnail 200x200!  '.$thumb;
    exec($exec, $exec_output, $exec_retval);
    
    $exec = '"C:\Program Files\ImageMagick-6.9.0-Q16\convert.exe" '.$name. "  -background White  label:ش.پ12355  -append  ".$name;
    exec($exec, $exec_output, $exec_retval);
    

    此代码有效。但每张图像的平均处理时间为1秒。 因此,对于100张图像,它可能需要大约100秒。

    如何加快整个过程(转换,调整大小,裁剪,水印)?

    修改

      

    我有一个服务器G8:Ram:32G,CPU:Intel Xeon E5-2650(4个过程)

         

    版本:ImageMagick 6.9.0-3 Q16 x64

         

    特点:OpenMP的

    convert logo: -resize 500% -bench 10 1.png
    
     Performance[1]: 10i 0.770ips 1.000e 28.735u 0:12.992
     Performance[2]: 10i 0.893ips 0.537e 26.848u 0:11.198
     Performance[3]: 10i 0.851ips 0.525e 27.285u 0:11.756
     Performance[4]: 10i 0.914ips 0.543e 26.489u 0:10.941
     Performance[5]: 10i 0.967ips 0.557e 25.803u 0:10.341
     Performance[6]: 10i 0.797ips 0.509e 27.737u 0:12.554
     Performance[7]: 10i 0.963ips 0.556e 25.912u 0:10.389
     Performance[8]: 10i 0.863ips 0.529e 26.707u 0:11.586
    

    资源限制:

      

    宽度:100MP;高度:100MP;面积:17.16GP;内存:7.9908GiB;地图:15.982GiB;磁盘:无限制;文件:1536;线程:8;节流:0;时间:无限

3 个答案:

答案 0 :(得分:4)

与往常一样,@ KurtPfeifle提供了一个极好的理由和解释的答案,他说的一切都是可靠的建议,你应该好好倾听并仔细遵循。

虽然可以做更多的事情,但它比我作为评论添加的更多,所以我把它作为另一个答案,尽管它只是对Kurt的增强......

我不知道Kurt使用的输出图像的大小,所以我制作了3000x2000之一,并将我的运行时间与他的比较,看看它们是否具有可比性,因为我们有不同的硬件。单个命令在我的机器上运行了42秒,流水线的命令在36秒内运行,所以我猜我的图像大小和硬件大致相似。

然后我使用GNU Parallel并行运行作业 - 我想你会从Xeon上获得很多好处。这就是我做的......

time for i in $(seq -w 1 100); do
    cat <<EOF
    convert image.tiff                                        \
     -respect-parentheses                                     \
     +write mpr:XY                                            \
      \( mpr:XY -resize 1024x                                 \
                +write image-1024-pipel-run-${i}.jpg     \)   \
      \( mpr:XY -thumbnail 200x200                            \
                +write image-thumb-pipel-run-${i}.jpg    \)   \
      \( mpr:XY -background white label:12345 -append         \
                +write image-labelled-pipel-run-${i}.jpg \)   \
     null:
   echo "DONE: run pipeline $i ..."
EOF
done | parallel

正如您所看到的,我所做的只是回显需要运行到stdout上的命令并将它们传送到GNU Parallel。 以这种方式运行,我的机器只需10秒钟。

我还尝试使用ffmpeg来模仿功能,并想出了这个,这在我的测试图像上看起来非常相似 - 你的里程可能会有所不同。

#!/bin/bash
for i in $(seq -w 1 100); do
    echo ffmpeg -y -loglevel panic -i image.tif ff-$i.jpg 
    echo ffmpeg -y -loglevel panic -i image.tif -vf scale=1024:682 ff-$i-1024.jpg
    echo ffmpeg -y -loglevel panic -i image.tif -vf scale=200:200 ff-$i-200.jpg
done | parallel

在我的iMac上使用3000x2000 image.tif输入文件在7秒内运行。

我无法在libturbo-jpeg下使用ImageMagick安装homebrew

答案 1 :(得分:3)

我一直听到一些人认为GraphicsMagick(几年前的分叉,从ImageMagick分支出来)明显快于ImageMagick。

所以我借此机会给它一个旋转。因此我的第二个答案。

我确实运行了以下4个独立gm命令的循环。这使得结果与我的其他答案中记录的4个单独的convert命令相当。它发生在同一台机器上:

time for i in $(seq -w 1 100); do 
 gm convert         image.tiff                         gm-${i}-image.jpg
 gm convert gm-${i}-image.jpg      -resize 1024x       gm-${i}-image-1024.jpg
 gm convert gm-${i}-image-1024.jpg -thumbnail 200x200  gm-${i}-image-thumb.jpg
 gm convert -background white    \
            gm-${i}-image-1024.jpg label:12345 -append gm-${i}-image-labelled.jpg
 echo "GraphicsMagick run no. $i ..."
done

结果时间:

real   1m4.225s
user   0m51.577s
sys    0m8.247s

这意味着:对于此特定作业,在此计算机上,我的Q8 GraphicsMagick(版本为1.3.20 2014-08-16 Q8)速度较慢, 64秒 比我的Q16 ImageMagick(版本为6.9.0-0 Q16 x86_64 2014-12-06)需要 50秒 ,每次运行100次。


当然,这个简短的测试及其结果绝不能作为防弹声明。

你可能会问:这台机器及其操作系统在进行每项测试时还做了什么?还有哪些其他应用程序同时加载到内存中?等等,你是对的。 - 但您现在可以自由运行自己的测试。你可以做的一件事就是为两个测试提供几乎相同的条件:在2个不同的终端窗口中同时运行它们!)

答案 2 :(得分:1)

我忍不住用vips来尝试这个基准。我使用了这两个脚本:

#!/bin/bash

for file in $*; do
        convert $file \
                -respect-parentheses \
                \( -clone 0 -resize 200x200 \
                        +write $file-thumb.jpg \)  \
                \( -clone 0 -resize 1024x \
                        -background white label:12345 -append \
                        +write $file-labelled.jpg \) \
                null:
done

和使用Python界面的vips:

#!/usr/bin/python

import sys
from gi.repository import Vips

for filename in sys.argv[1:]:
    im = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL)

    im = im.resize(1024.0 / im.width)
    mem = Vips.Image.new_memory()
    im.write(mem)

    thumb = mem.resize(200.0 / mem.width)
    thumb.write_to_file(filename + "-thumb.jpg")

    txt = Vips.Image.text("12345", dpi = 72)
    footer = txt.embed(10, 10, mem.width, txt.height + 20)
    mem = mem.join(footer, "vertical")

    mem.write_to_file(filename + "-labelled.jpg")

然后在100 3000 x 2000 RGB tiff图像与IM 6.8.9-9和vips 8.0,两者都与libjpeg-turbo,我看到:

$ time ../im-bench.sh * 
real    0m32.033s
user    1m40.416s
sys 0m3.316s
$ time ../vips-bench.py *
real    0m22.559s
user    1m8.128s
sys 0m1.304s