Every two weeks I send out a newsletter containing lots of interesting stuff for the modern PHP developer. You can expect quick tips, links to interesting tutorials, opinions and packages. Want to learn the cool stuff? Then sign up now!

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.

Freek Van der Herten is a partner and developer at Spatie, an Antwerp based company that specializes in creating web apps with Laravel. After hours he writes about modern PHP and Laravel on this blog. When not coding he’s probably rehearsing with his kraut rock band. He loves waffles and butterflies.
  • What are the main differences between this and Gregwar/Image?

    • On first glance Gregwar/Image doesn’t seem to have the `apply` method and the ability to pass it a sort of manipulations instance.

      • The wrapper around Glide is well written, no doubt, but this seems like it answers a problem that doesn’t exist. With the likes of Gregwar and Glide that cover all of the functionality that your package appears to cover. Its almost like this is a shot at re-inventing the wheel.

        Please correct me if you feel my information is inaccurate as I haven’t yet delved into your documentation line-by-line.

        • Well, like I mentioned in the previous comment our package provides an `apply` method and the ability to pass it a sort of manipulations instance. Our package also automatically converts to the filetype hinted by the output extension.

        • saka

          Why was Laravel created? Same reason, the author thought he can make something better than alternatives.

          This is php – a monkey with nothing better to do could write a library in a day. There most probably are already more than 200 PHP packages with this same purpose out there.

          Either you’re naive AF or you’re pushing your own shitty library in these comments.

          • I’ve got no library of my own to push – I’m purely stating that this seems like it’s reinventing the wheel. Laravel was a new architecture on a lot of existing libraries. The concept was the same but the execution was different. The impression I got from the docs was that it was the same purpose as more established libraries. At no point did I bash the authors, I was trying to ascertain what the advantages of this library were.

  • Pingback: Easily manipulate images in PHP with spatie/image | Bram.us()

  • another good package is intervention/image

  • Pingback: How To Upload Multiple Files in Laravel 5.4 - Laravel Daily()