Although it's fast and stable, this thing is not really ready for production. It needs some people to kick the tyres a bit and polish it up. I've tested on Linux and it's fine, OS X should work, Windows should be possible but would need some development. It's also php7-only, which might be a problem.
The neat thing about this binding is that it's dynamic. It has a fairly small 1,600 lines of C at the core which exposes the libvips introspection mechanism to PHP, and then a sub-1,000 line PHP skin over the top (much less if you ignore the phpdoc comments) which uses PHP magic methods to make every vips operation appear as a class method, and every vips property as a PHP property. This means that it's self-binding: if a new operator or a new option is added to libvips, it will automatically appear in PHP with no programming effort required. It will always be up to date.
Benchmarks
It runs at about the same speed as the other vips bindings. I made a repository to test it against the other PHP image processing libraries, imagick and gd. The test is the usual one:- Load a 5,000 x 5,000 pixel JPEG image.
 - Crop 100 pixels from every edge.
 - Shrink by 10% using a bilinear interpolator.
 - Sharpen with a 3x3 convolution.
 - Save back as a new JPEG image.
 
The gd convolution operator seems to be rather slow. If you comment out the sharpening stage from all the tests, the differences are a lot smaller:real time in seconds, fastest of three runs benchmark jpeg vips.php 0.53 imagick.php 1.96 gd.php 6.86 peak memory use in KB benchmark peak RSS vips.php 67024 gd.php 305620 imagick.php 519860
benchmark jpeg vips.php 0.41 imagick.php 1.20 gd.php 1.85
Example
It implements a fairly high-level interface, very like the Python and Ruby bindings. Here's the code for the benchmark:#!/usr/bin/env php <?php require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; $im = Vips\Image::newFromFile($argv[1], ["access" => "sequential"]); $im = $im->crop(100, 100, $im->width - 200, $im->height - 200); $im = $im->reduce(1.0 / 0.9, 1.0 / 0.9, ["kernel" => "linear"]); $mask = Vips\Image::newFromArray( [[-1, -1, -1], [-1, 16, -1], [-1, -1, -1]], 8); $im = $im->conv($mask); $im->writeToFile($argv[2]); ?>
Installing
This is rather painful. It comes in three main parts: the underlying library, the binary extension, and the php module.For the underlying library, you need libvips 8.0 or later, plus all the development headers. You can get this from your package manager on Linux or OS X. On Windows, you'll need to download a pre-compiled binary from the vips website. You can also build from source, of course.
The binary extension is vips-php-ext. This is not in pecl, so you'll need to clone the repository and make the package yourself. See the README for details, but the steps are roughly:
Finally, you can use the module in your project. Add:$ git clone git@github.com:jcupitt/php-vips-ext.git $ cd php-vips-ext $ pear package $ pear install vips-0.1.0.tgz
To your"require": { "jcupitt/vips" : "@dev" }
composer.json and you should be done.
What's not there
First the good news: all of vips is there, phpdoc is there and doc comments are written, and it's fast and stable. The bad news is that some obvious things are missing. There are issues in the php-vips tracker for them, but the big ones are:- The magic methods don't have phpdoc comments. You can call 
image->hough(), for example, to find the Hough transform of an image, but you're not going to discover that in the phpdoc output. There needs to be a little bit of code to generate @method comments for all the vips operators. - It needs some more phpdoc to introduce the library and show how to use it.
 - No exceptions. This should be simple to add, it's just not happened. Logging support would be useful too.
 - The in-place operations, like 
vips_circle(), can't be called. Again, this should be simple to fix. 
Just poking, but when trying to run the test on Windows, where should I extract the pre-compiled vips binary?
ReplyDeleteHi, sorry, I don't know how php extensions get built on Windows. I'd clone php-vips-ext and then start experimenting. If you can get to the point where it starts trying to compile things, it should be possible to work out where it's looking for vips.
ReplyDelete