Resize Images In Laravel 5.1 using intervention

We often need to manipulate Images for various purpose such as creating thumbnails or just simple resizing to fit proper size, it is quite cumbersome to perform these tasks in PHP, but intervention package make it so easy, we are going to use Intervention/image package to perform these tasks, intervention package has great documentation, you can crop, resize, grayscale, circle image and do tons of other stuff with ease, let's check it out.

What we are going to build

We are going to build image resize app, it will have a simple form which will contain file input and drop-down to select image size, on the submission of this form, we will resize the image.

devartisans - laravel image resize

Installing Dependencies

We need intervention package, for easy form creation we are going to get HTML package as well which is separately available from core Laravel.

Let's open composer.JSON file which exists in the root of your project, add intervention/image and illuminate/html dependencies to require object.

composer.json

{
"require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.1.*",
        
        //add These Two 
        "illuminate/html": "5.*",
        "intervention/image": "dev-master"
    }
}

Now run composer update command to get those packages.

composer update

In the config/app.php, we will now update the providers array with intervention and html providers:

app.php

<?php

'providers' => [

        // add these two at the bottom  
        Illuminate\Html\HtmlServiceProvider::class,
        Intervention\Image\ImageServiceProvider::class
]

We also need to add aliases for HTML, FORM and Image in aliases array so we can use them as façade, find the aliases array in config/app.php and add following facades:

<?php

'aliases' => [
         //add these three at the bottom
        'Form'      => Illuminate\Html\FormFacade::class, 
        'HTML'      => Illuminate\Html\HtmlFacade::class,
        'Image'     => Intervention\Image\Facades\Image::class
],

Creating necessary Routes

We have created three routes, we have get and post routes for media as well as one get media/show route for showing resized image.

routes.php

<?php

Route::get('media', [ 'as' => 'image.create', 'uses' => 'ImageController@create']);
Route::post('media', [ 'as' => 'image.store', 'uses' => 'ImageController@save']);
Route::get('media/show', [ 'as' => 'image.resized', 'uses' => 'ImageController@show']);
  • Get route for media will call create method in ImageController which is responsible for showing the form for image resize.

  • Post route for media is associated with save method of ImageController where the form will be posted, it will contain logic for resizing the image.

  • Get media/show route is going to call showImage method of ImageController, this method will show the image path and resized image.

Creating ImageController and associated route methods

Open the terminal, navigate to your project root  and run the following command to generate boilerplate for ImgaeController.

php artisan make:controller ImageController --plain

Once Controller has been created, you should see ImageController.php file in app/Http/controllers.

Now open ImageController.php file and add the create, save and show method, also include the Intervention\Image\Facades\Image namespace so we can use Intervention package.

For the sake of simplicity, we are not doing any validation and we are also creating logic for image resizing inside ImageController, which isn't necessarily great Idea, we should create service or repository for that, but this is fine for tutorial.

ImageController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Intervention\Image\Facades\Image; // Use this if you want facade style code
//use Intervention\Image\ImageManager // Use this if you don't want facade style code

class ImageController extends Controller
{
 
   	//showing form for uploading Image
   	public function create()
   	{
   		return view('images.create');
   	}

   	//saving image when form is posted
   	public function save(Request $request)
	{
        $image 			= 	$request->file('image');
        $resizedImage 	= 	$this->resize($image, $request->get('image_size'));
        
        if(!$resizedImage)
        {
        	return redirect()->back()->withError('Could not resize Image');
        }
    	return redirect()->route('image.resized')->with('image_url', asset('images'). '/' .$resizedImage->basename);
	}
	public function show()
	{
		$image_url = session('image_url');
		
		return view('images.show', compact('image_url'));
	}
	
	private function resize($image, $size)
    {
    	try 
    	{
    		$extension 		= 	$image->getClientOriginalExtension();
    		$imageRealPath 	= 	$image->getRealPath();
    		$thumbName 		= 	'thumb_'. $image->getClientOriginalName();
	    	
	    	//$imageManager = new ImageManager(); // use this if you don't want facade style code
    		//$img = $imageManager->make($imageRealPath);
	    
	    	$img = Image::make($imageRealPath); // use this if you want facade style code
	    	$img->resize(intval($size), null, function($constraint) {
	    		 $constraint->aspectRatio();
	    	});
	    	return $img->save(public_path('images'). '/'. $thumbName);
    	}
    	catch(Exception $e)
    	{
    		return false;
    	}

    }

    
}

create method returns create.blade.php view which contains a form for uploading Image.

save method gets form data when the form is posted and calls  private resize method to resize the image and redirect to image.resized route when resizing is done.

show method returns show.blade.php view which will show resized image as well as its path. 

Creating Views

We only need two views for showing image upload form and resized image so let's create these two views:

Navigate to resources/views and create images folder, inside this folder create show.blade.php(resources/views/images/show.blade.php) and create.blade.php(resources/views/images/create.blade.php) files, to save ourselves from repeating markup let's create master page resources/views/master.blade.php, it will contain our common HTML markup.

create.blade.php

@extends('master')

@section('content')
    @if(count($errors))
        <div class="alert alert-danger">
            <ul>
                @foreach($errors->all() as $error)
                     <li>{{ $error}}</li> 
                @endforeach
            </ul>
        </div>
    @endif
    
    <div class="col-md-6">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4>Resize Image</h4>
            </div>
            <div class="panel-body">
                <div class="row">
    
                    <div class="col-md-12">
                         <!-- Form for Saving Images -->
                        {!! Form::open([ 'route' => [ 'image.store' ], 'files' => true, 'enctype' => 'multipart/form-data' ]) !!}
    
                            <!-- File Input for Image -->
                            <div class="form-group">
                                {!! Form::label('image', 'Choose File : ') !!}
                                {!! Form::file('image', ['class' => 'custom-file-input' ]) !!}
                            </div>
    
                            <!-- Size for Image -->
                            <div class="form-group">
                                {!! Form::label('image_size', 'Select Image Dimension : ') !!}
                                {!! Form::select('image_size', ['200'=> '200', '400'=>'400', '600'=>'600']) !!}
                            </div>
                          
                            <!-- Submit Button Upload Image -->
                            <div class="form-group">
                                {!! Form::submit('Resize Image', [ 'class' => 'btn btn-default' ]) !!}
                            </div>
    
                        {!! Form::close() !!}
                    </div>
                </div>
    
            </div>
        </div>
    </div>
@stop

show.blade.php

@extends('master')

@section('content')
	<div>
		<p><strong>Path : </strong> {{ $image_url }}</p>
		<img src="{{ $image_url }}">
	</div>
@stop

master.blade.php

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="_token" content="{{ csrf_token() }}"/>
    <title>Document</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body {
            padding-top : 70px;
        }
    </style>
</head>
<body>
    <div class="container">
        @yield('content')
    </div>
</body>
</html>

That's it, now you should have working image resize application, in any case if you get errors, check the following common errors:

  • check if you have missed any comma while adding providers and aliases in config/app.php.

  • check  if you have added proper Intervention namespace in ImageController.php file. 

if you are having trouble, tell us in the comment section below or create the new thread in the forum.

Something to say? Tell us in comment section.