One of the requirements of my Laravel project is allowing users to upload a photo and post it. I didn’t want to set a low upload size because I know most of the users are going to be using their phone camera and those files can be very large. My solution was to allow large upload sizes but then resize the image before saving the file.

First we need to install Image Intervention in our project:


composer require intervention/image

In config/app.php we need to add this under providers:


'Intervention\Image\ImageServiceProvider',

and this under aliases:

 'Image' => 'Intervention\Image\Facades\Image', 

At the top of the Controller we need to declare it:

use Intervention\Image\ImageManagerStatic as Image;

Now that it’s all installed and ready to use we can look at the code for saving our image. This is how we would normally save an image:

if($request->file('uploadedFile')) {
       $image = $request->file('uploadedFile');
       $fileNameWithExt = $image->getClientOriginalName();
       $fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
       $extension = $image->getClientOriginalExtension();
       $fileNameToStore = $fileName."_".time().'.'.$extension;
       $image->storeAs('public/uploaded_images', $fileNameToStore);
}

With Image Intervention it looks like this:

if($request->hasFile('post_image')) {
    $image = $request->file('post_image');
    $fileNameWithExt = $image->getClientOriginalName();
    $fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
    $extension = $image->getClientOriginalExtension();
    $fileNameToStore = $fileName."_".time().'.'.$extension;
    $path = public_path('storage/uploaded_images/' . $fileNameToStore);
    Image::make($image->getRealPath())
        ->resize(800, 500, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        })
        ->save($path);
    }

Note the path. I had to try a few different ways of specifying where it was going to be saved, this is what works for Laravel.

The resize() function documentation is here:
http://image.intervention.io/api/resize
I used a callback function for two constraints: aspectRatio(), which resizes the image but keeps the original aspect ratio, and upsize(), which prevents the image from being upsized to the given size if the original is smaller.

Now the uploaded images are resized so they aren’t taking up a ton of storage space, they fit perfectly in the space I need them to, and the ratio isn’t distorted. If the uploaded image is smaller than the available space then they will display at their original size.