A package to easily manipulate images in PHP

Today we released a new package called image that makes manipulation images in PHP extremely easy. In this post I'd like to explain why we built it and how it can be used.

Manipulating images in PHP

To manipulate images in PHP there are already a lot of options. You can go hardcore and use the Gd or Imagick functions directly. By using them you get a lot of control, but most of these functions aren't very developer friendly. If you need something easier to work with try out the Intervention Image library by Oliver Vogel. It provides a nice abstraction and will make working with images a lot easier. Another option is a package by Jonathan Reinink called Glide. This one is a bit special. Glide can generate images on the fly using url parameters. With Glide installed in your project a cropped version of the image in this bit of html will be automatically generated.
<img src="image.jpg?w=300&h=400&fit=crop" />
Its API is really nice to work with. Under the hood Glide leverages the aforementioned Intervention Image but it hides some of the complex operations behind easy to use parameters. Unfortunately Glide only exposes its API via http, there's no way to easily programmatorically work with it.

Our image package

Enter spatie/image. Our new package wraps up Glide so all its methods can be used using PHP code.

Basic manipulation

In the remainder of this article we are going to manipulate this beautiful photograph taken in New York City. Let's start of with a simple manipulation.
Here's the result: Let's perform crop out that Starbucks storefront.
    ->manualCrop(600, 400, 20, 620)
Check out the documentation to learn which operations the package support.

Converting to other formats

Imagine you want to convert a jpg to a png. Here's how to do that.
It couldn't be more simpler, the package will just use the extension of the output file to determine the output format.

Applying changes

By default every manipulation will only be applied once to your image. When calling a manipulation method multiple times only the last call will be applied when the image is saved. Take a look at this code.
The second call to brightness will override the value set by the first call to brightness. So the resulting image will only have its brightness reduced by 20%. The apply method will apply all previous manipulations to the image before continuing with the next manipulations.
That code will lower the brightness by 40%, then lower it again by 20%. The result:

Preparing manipulations

In the previous examples all manipulations like brightness and blur were called directly on the Image instance. You could also opt to build up a Manipulations instance.
$manipulations = (new Manipulations())
and then you can use that to manipulate a collection of images.
//using Laravel's collect function

collect($images)->each(function(Image $image) use ($manipulations) {
The manipulate function can also accept a closure.
$image->manipulate(function(Manipulations $manipulations) {

In closing

You'll find more examples of how you can use spatie/image in the documentation. Right now we're using Glide behind the scenes to perform the manipulations, but we've built up our package in such a way that, in theory, we could swap Glide out for something else, without making any breaking changes. If you use Laravel and need a good solution to handle images and other files in your app, then check out our laravel-medialibrary package. We're releasing a new major version soon where all image manipulations are powered by spatie/image. Also take a look at the PHP and Laravel packages we've previously built. Maybe we've made something that you can use in your next project.

Finding differences in images with PHP

Over at Sitepoint Christoper Pitt shares some research he has done in finding differences in images using PHP.
I recently stumbled across a fascinating question: how could I tell whether an image had changed significantly? As PHP developers, the most troublesome image problem we have to deal with is how to resize an upload with an acceptable loss of quality. In the end I discovered what many before me have – that this problem becomes relatively simple given the application of some fundamental mathematical principles. Come along with me as we learn about them…