Beginners guide to image manipulation in Laravel
Tags: laravel, tutorial, webdev, beginners
Published: 2020-07-22 13:23:45

In almost all of the applications we write, there comes a point where we have to work with images, whether its for your homepage, profile or any other use image processing in vanilla PHP haven't always been the easiest task. This is where *Intervention* comes in. *Intervention* is a PHP Image Manipulation and Processing Library which provides a super simple way for us to *create,edit,resize and compose* images in our application.

##Getting started
In this example we'll take a look at how we can setup Intervention in Laravel. *Note: basic understanding of laravel is required for this tutorial*

####Install Laravel and setup database connection
In this demonstration, i am using Laravel 6.0, (current version is 7.x), any version can be used. Refer to [intervention documentation](http://image.intervention.io/)

Install laravel using composer.

```
composer create-project --prefer-dist laravel/laravel image-app "6.*"
```
Setup database connection in the.env file

```
//.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=image-app
DB_USERNAME=root
DB_PASSWORD=
```
Install front end dependencies, we will be using twitter bootstrap for styling.

```
composer require laravel/ui:1.0
php artisan ui bootstrap
npm install && npm run dev
```
####Database migration and Model Creation

```
php artisan make:model Product -mc
```
This command will create the database migration file, model and controller for our project.
1. Product.php (Model)
2. ProductController.php (Controller)
3. create_products_table.php (Migration file)

Open create_products_table.php and add the following.

```php
public function up()
    {
        Schema::create('images', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->string('image');
            $table->timestamps();
        });
    }
```
Now migrate the database to create Images table.
```
php artisan migrate
```
install Intervention package via composer
```
composer require intervention/image
```
Update routes/web.php file to handle form submission and displaying images

```php
Route::get('/', 'ProductController@index');
Route::post('/p', 'ProductController@store');
```

Create a view file. I am just modifying the default welcome.blade.php file shipped with laravel.

```php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

    </head>
    <body>

        <div class="container pt-5">

            <form action="/p" enctype="multipart/form-data" method="post">
                @csrf
                <div class="row">
                    <div class="col-7 offset-2">
                        
                        {{-- display success and error messages --}}
                        @if(session('success'))
                        <div class="alert alert-success">
                            {{ session('success') }}
                        </div>
                        @endif
                        @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            <strong>Whoops!</strong> There were some problems with your input.<br><br>
                            <ul>
                                @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                        @endif

                        <div class="row">
                            <h1>Add New Image</h1>
                        </div>
                        <div class="form-group row">
                            <label for="title" class="col-md-4 col-form-label">Title</label>
                            <input id="title"
                            type="text"
                            class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}"
                            name="title"
                            value="{{ old('title') }}"
                            autocomplete="title" autofocus>
                            @if ($errors->has('title'))
                            <span class="invalid-feedback" role="alert">
                                <strong>{{ $errors->first('title') }}</strong>
                            </span>
                            @endif
                        </div>
                        <div class="row">
                            <label for="image" class="col-md-4 col-form-label">Post Image</label>
                            <input type="file" class="form-control-file" id="image" name="image">
                            @if ($errors->has('image'))
                            <strong>{{ $errors->first('image') }}</strong>
                            @endif
                        </div>
                        <div class="row pt-4">
                            <button class="btn btn-primary">Add New Post</button>
                        </div>
                    </div>
                </div>
            </form>
        </div>

        <div class="container pt-5">
            <div class="row">
                @foreach ($products as $product)
                <div class="col-4">
                    <img src="/storage/{{ $product->image }}" class="w-100">
                    <h5 class="pt-2">{{ $product->title }}</h5>
                </div>
                @endforeach
            </div>
        </div>
        
    </body>
</html>

```
Update Product.php to enable fillable form fields.

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    //
    protected $guarded = [];
}
```
Update ProductController.php 

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
use App\Product;

class ProductController extends Controller
{
    public function index()
    {
    	$products = Product::get();
    	return view('welcome', compact('products'));
    }

    public function store()
    {
    	$data = request()->validate([
            'title' => 'required',
            'image' => ['required', 'image'],
        ]);

        $imagePath = request('image')->store('uploads', 'public');

        //intervention magic happens here, we are resizing the image before saving to db
        $image = Image::make(public_path("storage/{$imagePath}"))->fit(1200, 1200);
        $image->save();

        \App\Product::create([
        	'title' => $data['title'],
        	'image' => $imagePath,
        ]);

        return redirect('/')->with('success', 'Your image has been successfully Uploaded');;
    }
}

```
Finally create a symlink between the app storage folder and public folder.

run this command in the terminal

```
php artisan storage:link
```
run the app in the terminal 

```
php artisan serve
```
That is how we use intervention image to manipulate images in our application, intervention image is a powerful library with endless possibilities so dig through their [documentation](http://image.intervention.io/) to see advanced concepts.

Here is the final result. Using intervention library we are resizing the images with no additional configuration, before saving to database. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ha7wocemxp3z83zzu97a.png)