Upload & Resize Images With Laravel Intervention Image

Laravel Intervention Image

Let’s create a Trait to upload, resize, delete and manipulate images by Intervention Image, the Laravel & PHP image handling, and manipulation library.

Intervention Image provides an easy and expressive way to manipulate images. I have been using it for years. I did everything I want with it from resizing and adding watermarks to composing images. Its classes and functions are very easy to use, and understand how they work.

In this tutorial, we will create a Trait for uploading and resizing images then saving them in storage and deleting them as well.

If you don’t like to read, you can see this video on YouTube: Upload & Resize Images with Intervention Image In Laravel API and Create Thumbnails

Intervention Image installation

I’m using Laravel 9, let’s install it via composer

composer require intervention/image

In config/app.php file, let’s add the following class to $providers array

Intervention\Image\ImageServiceProvider::class

In the same file, let’s add the facade of this package to the $aliases array.

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

Make sure  PHP’s GD library extension is active

Laravel Intervention Image Trait

Let’s create a trait with all the functions we need to manipulate our images so we can call these functions whenever we want.

Create file and folder in app\Traits\ImageProcessing.php and create our trait

<?php
namespace App\Traits;
use Image;
use Storage;
use Illuminate\Support\Str;

trait ImageProcessing{

}

The first function we create in our trait is for getting the image extension by mime of the uploaded file so we can use it in renaming the file later.

public function get_mime($mime){
        if ($mime == 'image/jpeg')
        $extension = '.jpg';
       elseif ($mime == 'image/png')
        $extension = '.png';
       elseif ($mime == 'image/gif')
        $extension = '.gif';
      elseif ($mime == 'image/svg+xml')
       $extension = '.svg';
       elseif ($mime == 'image/tiff')
       $extension = '.tiff';
       elseif ($mime == 'image/webp')
       $extension = '.webp';
    
       return $extension ;

    }

Let’s create a function for saving the image and renaming the file with a random string and date, for making sure no overriding with current or new images in our storage.

public function saveImage($image){
        $img = Image::make($image);
        $extension = $this->get_mime($img->mime());

        $str_random = Str::random(8);
        $imgpath = $str_random.time().$extension;
        $img->save(storage_path('app/imagesfp').'/'.$imgpath);

        return $imgpath;
    }

We return the $imgpath with the image path so we can save it in our database. We pass the storage path to $img->save() for saving the image in it.

The next function here is for resizing the image. We will add the width and height that we want and we will use $constraint->aspectRatio(); to keep the aspect ratio of the image so that the largest side fits within the limit and the smaller side will be scaled to maintain the original aspect ratio.

 public function aspect4resize($image,$width,$height){
      $img = Image::make($image);
      $extension = $this->get_mime($img->mime());
      $str_random = Str::random(8);

      $img->resize($width,$height,function($constraint){
        $constraint->aspectRatio();
      });

      $imgpath = $str_random.time().$extension;
      $img->save(storage_path('app/imagesfp').'/'.$imgpath);
    
      return $imgpath;

   }

But if we want to keep the height and only crop the width or resize it, we use the next function.

 public function aspect4height($image,$width,$height){
    $img = Image::make($image);
    $extension = $this->get_mime($img->mime());
    $str_random = Str::random(8);
    $img->resize(null,$height,function($constraint){
        $constraint->aspectRatio();
    });

    if($img->width() < $width){
      $img->resize($width, null);
    }
    else if($img->width() > $width){
     $img->crop($width, $heigh, 0, 0);
    }

    $imgpath = $str_random.time().$extension;
    $img->save(storage_path('app/imagesfp').'/'.$imgpath);
    return $imgpath;


   }

We can use all the above functions separately. But if we want one function to save the original image and create thumbnails we should create the below function that returns an array will all the images’ paths.

 public function saveImageAndThumbnail($Thefile,$thumb = false){
    $dataX = array();

    $dataX['image'] = $this->saveImage($Thefile); 

    if($thumb){
       
        $dataX['thumbnailsm']= $this->aspect4resize($Thefile,256,144);
        $dataX['thumbnailmd']= $this->aspect4resize($Thefile,426,240);
        $dataX['thumbnailxl']= $this->aspect4resize($Thefile,640,360);
    }
    
    return $dataX;
    }

Finally in our traits, the delete function. We just pass the image path from our database and it will delete it.

public function deleteImage($filePath){
    if($filePath){
      if(is_file(Storage::disk('imagesfp')->path($filePath))){
          if(file_exists(Storage::disk('imagesfp')->path($filePath))){
              unlink(Storage::disk('imagesfp')->path($filePath));  
          }
      }
    }
}

Using The trait

We call our trait in our controller like the below code.

use App\Traits\ImageProcessing;
class ProductController extends Controller
{
use ImageProcessing,
 public function store(ProductStoreRequest $request)
    {
//
     if($request->hasFile('image')){
            $dataX =  $this->saveImageAndThumbnail($request->file('image'),true);
            $data['image']  =  $dataX['image'];
            $data['thumbnailsm']  =  $dataX['thumbnailsm'];
            $data['thumbnailmd']  =  $dataX['thumbnailmd'];
            $data['thumbnailxl']  =  $dataX['thumbnailxl'];
        }
      $product = Product::create($data);
//
    }
}

To get the images’ URL, we use Laravel Storage class as the following

'image' => $this->image? Storage::disk('imagesfp')->url($this->image):'',
'thumbnailsm' => $this->thumbnailsm? Storage::disk('imagesfp')->url($this->thumbnailsm):'',
'thumbnailmd' => $this->thumbnailmd? Storage::disk('imagesfp')->url($this->thumbnailmd):'',
'thumbnailxl' => $this->thumbnailxl? Storage::disk('imagesfp')->url($this->thumbnailxl):'',

Leave a Reply

Your email address will not be published. Required fields are marked *