Create Thumbnail in Laravel Using Intervention Image Library

On the website, we always deal with the images. Based on the website’s structure, we use different versions of images. It’s always a good practice to create distinct versions aka thumbnails of a single image. These thumbnails can be used while displaying separate sizes of images depending on the container size. Showing an image that fits as per container size will save bandwidth and improves page load time. Showing a large size image in a small container is a bad practice and compromises page speed. As a result, it’s recommended to create multiple thumbnails of an image and use the appropriate version wherever necessary.

In this article, we study how to create a thumbnail in Laravel using the Intervention Image library. To generate thumbnails, I’ll use the Intervention Image which is free and one of the popular library for image manipulation. Under the hood, this library uses the GD Library and Imagick for image manipulation.

For this tutorial, I will create 3 thumbnails – small, medium, and large with sizes 150*93, 300*185, and 550*340 respectively. Change these sizes as per your requirement.

Getting Started

In order to get started, you first need to install the Intervention Image library in Laravel. Open the terminal in your project root directory and run the command below:

composer require intervention/image

After installing the library, open the config/app.php file and add the following lines to it.

Include the service providers of this package in the $providers array.

Intervention\Image\ImageServiceProvider::class

Add the package’s facade to the $aliases array.

'Image' => Intervention\Image\Facades\Image::class

Next, to store the images we need to create a directory. Head over to the terminal and run the command as follows:

php artisan storage:link

This command creates a symbolic link from public/storage to storage/app/public. In this public/storage folder, I’ll upload the original image and its thumbnails.

Create a Thumbnail in Laravel

We are all set with the basic setup and can now write the actual code. Let’s create a form in the image.blade file.

@if (session('success'))
    <strong>{{ session('success') }}</strong>
@endif

<form action="{{ url('store') }}" method="post" enctype="multipart/form-data">
    @csrf
    <p>
       Upload Image: <input type="file" name="profile_image" />
    </p>
    <button type="submit" name="submit">Submit</button>
</form>

Here I passed the action URL as store. I’ll map this route with the ImageController. Run the below command to create this controller.

php artisan make:controller ImageController

Next, define the below routes in the routes/web.php file.

Route::get('image', 'ImageController@index');
Route::post('store', 'ImageController@store');

In the controller, let’s add the Image facade and call the view from the index() method.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Image;

class ImageController extends Controller
{
    public function index()
    {        
        return view('image');
    }
}

By adding the facade, we are able to use methods of the Intervention Image library.

In the below code, I will upload the image in two places. The original image goes directly inside the storage/profile_images folder. The thumbnails would be stored under the storage/profile_images/thumbnail directory. We first upload the original image in the thumbnail folder and then resize it.

public function store(Request $request)
{
    if($request->hasFile('profile_image')) {
        //get filename with extension
        $filenamewithextension = $request->file('profile_image')->getClientOriginalName();
 
        //get filename without extension
        $filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
 
        //get file extension
        $extension = $request->file('profile_image')->getClientOriginalExtension();
 
        //filename to store
        $filenametostore = $filename.'_'.time().'.'.$extension;
 
        //small thumbnail name
        $smallthumbnail = $filename.'_small_'.time().'.'.$extension;
 
        //medium thumbnail name
        $mediumthumbnail = $filename.'_medium_'.time().'.'.$extension;
 
        //large thumbnail name
        $largethumbnail = $filename.'_large_'.time().'.'.$extension;
 
        //Upload File
        $request->file('profile_image')->storeAs('public/profile_images', $filenametostore);
        $request->file('profile_image')->storeAs('public/profile_images/thumbnail', $smallthumbnail);
        $request->file('profile_image')->storeAs('public/profile_images/thumbnail', $mediumthumbnail);
        $request->file('profile_image')->storeAs('public/profile_images/thumbnail', $largethumbnail);
 
        //create small thumbnail
        $smallthumbnailpath = public_path('storage/profile_images/thumbnail/'.$smallthumbnail);
        $this->createThumbnail($smallthumbnailpath, 150, 93);
 
        //create medium thumbnail
        $mediumthumbnailpath = public_path('storage/profile_images/thumbnail/'.$mediumthumbnail);
        $this->createThumbnail($mediumthumbnailpath, 300, 185);
 
        //create large thumbnail
        $largethumbnailpath = public_path('storage/profile_images/thumbnail/'.$largethumbnail);
        $this->createThumbnail($largethumbnailpath, 550, 340);
 
        return redirect('image')->with('success', "Image uploaded successfully.");
    }
}

The above code stores the image in 3 versions – small, medium, and large. After storing them we are calling the method createThumbnail() along with the width and height values. Let’s define this function below. This method should go into the same ImageController.

/**
 * Create a thumbnail of specified size
 *
 * @param string $path path of thumbnail
 * @param int $width
 * @param int $height
 */
public function createThumbnail($path, $width, $height)
{
    $img = Image::make($path)->resize($width, $height, function ($constraint) {
        $constraint->aspectRatio();
    });
    $img->save($path);
}

Here I am resizing the images proportionally. It will keep the aspect ratio and the image will not cut off.

If you are looking for a hard crop then replace the below lines

$img = Image::make($path)->resize($width, $height, function ($constraint) {
    $constraint->aspectRatio();
});
$img->save($path);

With

$img = Image::make($path)->resize($width, $height)->save($path);

I hope you understand how to create a thumbnail in Laravel using the Intervention Image library. I would like to hear your thoughts and suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

6 thoughts on “Create Thumbnail in Laravel Using Intervention Image Library

  1. thank you sir this nice post , but i have one question how to use these thumbnails in img src path.

    Sorry I am new in laravel so plzzz kindly help me

  2. Also can you explain the bit bit where you upload the files…
    //Upload File
    $request->file(‘uploaded_file’)->storeAs(‘public/uploaded_files’, $filenametostore);
    $request->file(‘uploaded_file’)->storeAs(‘public/uploaded_files/thumbnail’, $smallthumbnail);
    $request->file(‘uploaded_file’)->storeAs(‘public/uploaded_files/thumbnail’, $mediumthumbnail);
    $request->file(‘uploaded_file’)->storeAs(‘public/uploaded_files/thumbnail’, $largethumbnail);

    But then you create the thumbnail?

    $smallthumbnailpath = public_path(‘storage/uploaded_files/thumbnail/’.$smallthumbnail);
    $this->createThumbnail($smallthumbnailpath, 150, 93);

    Seems backwards?

    Thanks

    1. This library only works with the image. For video, you may want to try another solution like FFmpeg.

Leave a Reply

Your email address will not be published.