Resize images using Laravel and Intervention Image
Intervention Image is an open source PHP image handling and manipulation library. It provides an easier and expressive way to create, edit, and compose images and supports currently the two most common image processing libraries GD Library and Imagick.
The class is written to make PHP image manipulating easier and more expressive. No matter if you want to create image thumbnails, watermarks or format large image files Intervention Image helps you to manage every task in an easy way with as little lines of code as possible.
Step 1: Create your project
After installing the Laravel framework on our machine, we create a new project with the following command:
laravel new file-upload
After the installation is complete, we use the console to install the package which is required to change the size of our uploaded image:
composer require intervention/image
Step 2: Setup Intervention Image package
Now we are setting up our project according to the documentation of InterventionImage.
After you have installed Intervention Image, open your Laravel config file config/app.php
and add the following lines.
In the $providers
array add the service providers for this package.
Intervention\Image\ImageServiceProvider::class
Add the facade of this package to the $aliases
array.
'Image' => Intervention\Image\Facades\Image::class
Optional we can publish the config file of the package to the config
directory of our project.
php artisan vendor:publish --provider="Intervention\Image\ImageServiceProviderLaravelRecent"
For older versions of Laravel use the following command:
php artisan config:publish intervention/image
Step 3: Link the Laravel storage directory
We need to create a shortcut to the storage directory in order to access it from the public directory. Use the following command, which will create a shortcode called storage
at your public directory.
php artisan storage:link
Step 4: Create controller and a basic view
Create an upload controller called ImageUpladContoller
:
php artisan make: controller ImageUploadController
In the next step we will create a basic view to output our html layout. Create a file with the name upload.blade.php
at the location resources/views
and fill it with the following lines of code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" >
<title>{{ config('app.name', 'Laravel') }} - @yield('title')</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col">
<form method="post" action="/image/upload" enctype="multipart/form-data">
<div class="form-group">
<label>Upload image</label>
<input type="file" class="form-control-file" name="image">
</div>
<div class="form-group">
<button type="submit" name="submit">Upload</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Add the route to the routes/web.php
file, used in the form. The route calls the upload
method, which we’ll create in the next step.
Route::post('/image/upload', 'ImageUploadController@upload');
Step 5: Fill the ImageUploadController with code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Image;
class DeviceController extends Controller
{
/**
* Uploads a new image.
*
* @param mixed $request
* @author Niklas Fandrich
* @return mixed
*/
public function upload(Request $request) {
$this->validate($request, [
'image' => 'image|mimes:jpeg,png,jpg,gif,svg',
]);
$this->storeImage($request);
}
/**
* Prepares a image for storing.
*
* @param mixed $request
* @author Niklas Fandrich
* @return bool
*/
public function storeImage($request) {
// Get file from request
$file = $request->file('image');
// Get filename with extension
$filenameWithExt = $file->getClientOriginalName();
// Get file path
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Remove unwanted characters
$filename = preg_replace("/[^A-Za-z0-9 ]/", '', $filename);
$filename = preg_replace("/\s+/", '-', $filename);
// Get the original image extension
$extension = $file->getClientOriginalExtension();
// Create unique file name
$fileNameToStore = $filename.'_'.time().'.'.$extension;
// Refer image to method resizeImage
$save = $this->resizeImage($file, $fileNameToStore);
return true;
}
/**
* Resizes a image using the InterventionImage package.
*
* @param object $file
* @param string $fileNameToStore
* @author Niklas Fandrich
* @return bool
*/
public function resizeImage($file, $fileNameToStore) {
// Resize image
$resize = Image::make($file)->resize(600, null, function ($constraint) {
$constraint->aspectRatio();
})->encode('jpg');
// Create hash value
$hash = md5($resize->__toString());
// Prepare qualified image name
$image = $hash."jpg";
// Put image to storage
$save = Storage::put("public/images/{$fileNameToStore}", $resize->__toString());
if($save) {
return true;
}
return false;
}
}
Explanation:
- In the
upload
method we validate the image and pass it to thestoreImage
method. - The
storeImage
method analyzes the image and creates a unique file name. - In the
resizeImage
method we finally call theImage
class, change the size of the image and save it in thestorage
directory.
The uploaded image should now be available at the following URL:
http://localhost/storage/images/filename.jpg
Now you can store the filename at a database and display it in your views, e.g. like this:
<img src="{{ $url('/') }}/storage/images/{{ $filename }}" alt="An image">