ImageMagick 是覆盖图像的最快方法吗?我怎样才能做得更快,或者有没有我不知道的更快的技术?

Posted

技术标签:

【中文标题】ImageMagick 是覆盖图像的最快方法吗?我怎样才能做得更快,或者有没有我不知道的更快的技术?【英文标题】:Is ImageMagick the fastest way to overlay images? How do I make faster or is there a faster tech I'm unaware of? 【发布时间】:2018-04-05 21:21:05 【问题描述】:

我正在构建一个图像处理 nginx CDN/缓存服务器,以在服装 jpeg 上覆盖数百万个独特的 SVG 设计文件。类似的教程在这里:http://sumitbirla.com/2011/11/how-to-build-a-scalable-caching-resizing-image-server/

我在这里写了一个测试脚本:

<?php

$cmd = "composite GOSHEN.svg blank-tshirt.jpg -geometry 600x700+456+335 JPG:-";

header("Content-type: image/jpeg");
passthru($cmd);
exit();

?>

这是一个示例结果:

我的问题是 ImageMagick 太慢了。除了更多的 CPU/内存,还有什么技巧可以让它更快吗?是否有任何替代技术可以更快地叠加图像?

非常感谢任何帮助。

【问题讨论】:

我过去做过一些速度测试,GD 和 Imagick 可以比 Imagemagick 更快。 Imagemagick 是一个外部程序,而 Imagick 和 GD 是内置在 php 中的。我会尝试测试并比较所有三个,看看你会得到什么。 您可以使用 html5 Canvas Composite 和 SVG 选项进行叠加。见w3schools.com/html/html5_canvas.aspdeveloper.mozilla.org/en-US/docs/Web/API/…。我不能说我已经使用过它们,但这是一种快速的方法。 Python/OpenCV 也可能比 GM 或 IM 更快。 你说你想做几百万次叠加。你的意思是把它们全部做,预先,作为一个大批量?或者你会在需要的时候按需做每一个?这是两个不同的问题。 【参考方案1】:

php-vips 可以比imagick 快很多。我为你做了一个测试程序:

#!/usr/bin/env php
<?php

require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;

for($i = 0; $i < 100; $i++) 
    $base = Vips\Image::newFromFile($argv[1], ["access" => "sequential"]);
    $overlay = Vips\Image::newFromFile($argv[2], ["access" => "sequential"]);

    // centre the overlay on the image, but lift it up a bit    
    $left = ($base->width - $overlay->width) * 0.5;
    $top = ($base->height - $overlay->height) * 0.45;

    $out = $base->composite2($overlay, "over", ["x" => $left, "y" => $top]);

    // write to stdout with a mime header
    $out->jpegsave_mime();
       

使用来自您服务器的测试图像:

http://build9.hometownapparel.com/pics/

然后在我的台式机上运行(Ubuntu 17.10,一个快速的 i7 CPU)我看到了:

$ time ./overlay.php blank-tshirt.jpg GOSHEN.svg > /dev/null
real    0m2.488s
user    0m13.446s
sys 0m0.328s

所以每张图片大约需要 25 毫秒。我看到了这个结果(显然来自第一次迭代):

我尝试了您的 imagemagick 示例的循环版本:

#!/usr/bin/env php
<?php

header("Content-type: image/jpeg");

for($i = 0; $i < 100; $i++) 
    $cmd = "composite GOSHEN.svg blank-tshirt.jpg -geometry 600x700+456+335 JPG:-";

    passthru($cmd);
     

针对 IM-6.9.7-4(为 Ubuntu 打包的版本)运行它我看到了:

$ time ./magick.php > /dev/null
real    0m29.084s
user    0m42.289s
sys 0m4.716s

或每张图像 290 毫秒。所以在这个测试中,php-vips 快了 10 倍以上。这有点不公平:imagick 可能会比直接合成要快一些。

这里还有另一个基准:

https://github.com/jcupitt/php-vips-bench

在这一点上,php-vips 比 imagick 快 4 倍,并且需要的内存减少 8 倍。

这是打包为 Dockerfile 的全部内容,您应该可以在任何地方运行:

https://github.com/jcupitt/docker-builds/tree/master/php-vips-ubuntu-16.04

【讨论】:

感激不尽。这些基准速度使我能够构建我的解决方案。这是一段非常漫长的艰难研究之旅,我一遍又一遍地把头撞在墙上。谢谢。 是的,25 毫秒已经足够快,您可以将其作为页面生成的一部分。 仅供参考。我让 php-vips 在我的服务器上工作。安装过程很艰难,但我最初的实际测试显示 libvips 的运行速度比 ImageMagick 快 9-10 倍。更多的人需要了解这个很棒的软件。再次感谢您的所有帮助。 哦,没问题,我很高兴它能正常工作。安装很棘手,主要是因为 Ubuntu 16.04 打包了一个相当旧的 libvips 版本并且必须更新。安装应该是 18.04 的两班(我认为),两周后到期。 我添加了一个打包好的 dockerfile。它应该使安装更简单。

以上是关于ImageMagick 是覆盖图像的最快方法吗?我怎样才能做得更快,或者有没有我不知道的更快的技术?的主要内容,如果未能解决你的问题,请参考以下文章

使用 ImageMagick 自动调整大小覆盖两个图像

我可以使用ImageMagick来确定X轴和Y轴的长度吗?

imagemagick:调整大小后如何获取图像大小?

Imagemagick合并图片批处理

我可以使用 Python 访问 ImageMagick API 吗?

ImageMagick,调整图像大小的最有效方法?