4

我正在编写一个小 CMS,您可以在其中上传几张图片。这些图像使用 imagemagick转换为3 个版本(大、中和缩略图大小) 。

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

这是带有 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

4 回答 4

9

我最近遇到了同样的问题,但我只通过图像一次将它们从原来的 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 示例——API 和脚本中遇到了以下内容,这可能会有所帮助:

  • “Shell 脚本本来就很慢。它被解释,需要多个步骤和额外的文件处理到磁盘。这当然更好,这要归功于新的 IM v6 选项处理,允许您在单个命令中执行大量图像处理操作. 即使这样你也很少能在一个convert命令中完成所有事情,所以你经常不得不使用多个命令来实现你想要的。”

  • “当读取大量甚至大量图像时,最好使用读取修改器来调整大小或裁剪它们,因为 IM 不会将它们读取完整图像,从而减少其内存需求。”

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

于 2012-04-18T13:28:18.187 回答
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 个不同大小的图像。

于 2012-04-21T07:57:01.177 回答
2

等什么?从上传的三张图片生成 12 张图片不应该需要五分钟。

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

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

于 2012-04-17T11:03:03.063 回答
0

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

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

  • 如果源相对较小(比如 1024x768),调整大小是否需要相当长的时间?
  • 直接从外壳调用是否需要相同的时间?

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

于 2012-04-17T11:03:47.967 回答