Wyatt Jackson
Wyatt Jackson

Reputation: 303

Is ImageMagick the fastest way to overlay images? How do I make faster or is there a faster tech I'm unaware of?

I'm in the process of building an image manipulation Nginx CDN/cache server to overlay millions of unique SVG designs files on apparel jpegs. Similar tutorial here: http://sumitbirla.com/2011/11/how-to-build-a-scalable-caching-resizing-image-server/

I have written a test script here:

<?php

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

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

?>

Here is an example result:

My issue is that ImageMagick is so slow. Besides more CPU/Memory, are there any tricks to make it faster? Are there any alternative technologies that could be faster to overlay images?

Any help is much appreciated.

Upvotes: 3

Views: 1900

Answers (1)

jcupitt
jcupitt

Reputation: 11190

php-vips can be quite a bit quicker than imagick. I made a test program for you:

#!/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();
}       

Using the test images from your server:

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

Then running on my desktop machine (Ubuntu 17.10, a fast i7 CPU) I see:

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

So about 25ms per image. I see this result (taken from the first iteration, obviously):

sample output

I tried a looping version of your imagemagick example:

#!/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);
}     

Running it against IM-6.9.7-4 (the version packaged for Ubuntu) I see:

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

Or 290ms per image. So on this test, php-vips is more than 10x faster. It's a bit unfair: imagick would probably be a little quicker than just shelling out to composite.

There's another benchmark here:

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

On that one, php-vips is about 4x faster than imagick and needs 8x less memory.

Here's the whole thing packaged as a Dockerfile you should be able to run anywhere:

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

Upvotes: 6

Related Questions