DEV Community

Cover image for Beginners guide to image manipulation in Laravel
Mizuan Mohamed
Mizuan Mohamed

Posted on

Beginners guide to image manipulation in Laravel

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

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.

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

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.

<!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

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    //
    protected $guarded = [];
}

Update ProductController.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 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

Top comments (1)

Collapse
 
wing profile image
Wing

This is perfect thank you!