使用imagemagick创建图片太慢了。如何提高?

时间:2012-04-17 10:56:43

标签: php imagemagick

我正在编写一个小型CMS,您可以在其中上传多个图像。 这些图像通过imagemagick转换为 3版本(大,中和缩略图大小)

问题是imagemagick需要5分钟才能创建4张图片的3个版本(已上传)。

这是带有imagemagick命令的部分:

foreach($upIMGS as $key => $filename){
    list($width, $height) = getimagesize($path.$filename);
    if ($width > $height) $size = "x96";
    else $size = "96x";

    exec(P_IMAGEMAGICK." ".$path.$filename." -resize $size -gravity center -crop 96x96+0+0 +repage ".$path."th-".$filename);
    exec(P_IMAGEMAGICK." ".$path.$filename." -resize 320x320 ".$path."hl-".$filename);
    exec(P_IMAGEMAGICK." ".$path.$filename." -resize 514x ".$path."fl-".$filename);

    unlink($path.$filename);
}

[$ upIMGS是一个包含最近上传图片的所有文件名的数组]

我的意思是..它确实有效,但太慢了,5分钟后服务器给我一个错误。一些文件是生成的,有些不是......

如果你能给我一个提示,那将是非常好的。

4 个答案:

答案 0 :(得分:7)

我最近遇到了同样的问题,但我只是通过图片一次将它们从原来的2592x1944调整为300xbestFit或bestFitx300

我正在使用PHP类imagick而不是命令行,但在我的情况下,我通过更改为-scale或scaleImage将时间缩短了一半。这是我的测试代码的片段。

while ($images = readdir($handle)) {
    // check to see if the first or second character is a '.' or '..', 
    // if so then remove from list
    if (substr($images,0,1) != '.') {
        //Check files to see if there extensions match any of the following image extensions. 
        // GLOB_BRACE looks for all glob criteria within the {braces}
        $images = glob($dir."{*.gif,*.jpg,*.png,*.jpeg}", GLOB_BRACE);
        // the glob function gives us an array of images
        $i = 0;
        foreach ($images as $image) {
            // parse the data given and remove the images/ $dir, 
            // imagemagick will not take paths, only image names.
            $i++;
            list ($dir, $image) = split('[/]', $image);
            echo $i, " ", $image, "<br />";

            $magick = new Imagick($dir."/".$image);
            $imageprops = $magick->getImageGeometry();

            if ($imageprops['width'] <= 300 && $imageprops['height'] <= 300) {
                // don't upscale
            } else {

                // 29 Images at 2592x1944 takes 11.555036068 seconds -> 
                // output size = 300 x 255
                $magick->scaleImage(300,300, true);

                // 29 Images at 2592x1944 takes 23.3927891254 seconds -> 
                // output size = 300 x 255
                //$magick->resizeImage(300,300, imagick::FILTER_LANCZOS, 0.9, true);
                $magick->writeImage("thumb_".$image);

            }
        }
    }
}

我正在2592x1944处理29张图像,从23.3927891254秒到11.555036068秒。我希望这会有所帮助。

修改

除了我上面所说的,我刚刚在ImageMagick v6 Examples -- API & Scripting上遇到了以下内容,这可能会有所帮助:

  • “Shell脚本本质上很慢。它被解释,需要 多个步骤和对磁盘的额外文件处理。这当然是 更好的归功于新的IM v6选项处理,让您可以做到 单个命令中的大量图像处理操作。甚至 所以你很少能在一个convert命令中完成所有工作 你经常需要使用多个命令才能达到你想要的效果。“

  • “在阅读大量甚至大量图像时,最好是 使用Read Modifier来 调整大小,或裁剪它们,因为IM不会在完整图像中读取, 从而减少了它的内存需求。“

  • “如果您将ImageMagick称为Apache模块,它也会减少 启动时间,因为部件将被加载一次并保持可用 多次使用,而不是一遍又一遍地重新加载。这可能 通过永久运行,在未来变得更加实用 '守护进程'IM进程。“

答案 1 :(得分:3)

这个例子可能会有所帮助,因为它会将主图像加载到内存中并对其进行处理以制作其他图像:

$cmd = " input.jpg \( -clone 0 -thumbnail x480 -write 480_wide.jpg +delete \)". 
" \( -clone 0 -thumbnail x250 -write 250_wide.jpg +delete \) ". 
" \( -clone 0 -thumbnail x100 -write 100_wide.jpg +delete \) -thumbnail 64x64! null: ";
exec("convert $cmd 64_square.jpg ");

这会创建4种不同尺寸的图像。

答案 2 :(得分:2)

等什么?从三张上传的照片中生成12张照片不应该花费五分钟。

我没有看到你的其余代码,但为什么你的getimagesize路径是$ path。$ filename但是你取消链接P_UPLOADS。$ value?他们有什么不同的原因吗?无论如何,$ value来自哪里,它在foreach()循环中没有定义。也许你只是有一个导致脚本挂起的错误。我已经使用了ImageMagick(虽然没有使用exec(),但是使用了实际的类)并且速度非常快。

您是否在foreach循环()上运行诊断程序?就像打印毫秒执行每个exec()命令一样。

答案 3 :(得分:0)

一个小技巧是首先创建最大的图片,然后从这个创建后续图片,而不是原始图片。

然而,无论如何,5分钟对于仅仅12张图像来说似乎太多了 你必须做一些调查。

  • 如果源相对较小(例如1024x768),调整大小需要相当长的时间吗?
  • 是否需要直接从shell调用它?

如果延迟是不可避免的,您可能希望将调整大小设施移动到专用服务器,将它们放入队列并使用简单的AJAX片段检查该过程。