Laravel 10 Crop Image Before Upload

Hello Artisan, Today I'll show you how to crop images before uploading in our Laravel application. For that, we're going to use Croppie JS. Croppie js allows us to easily crop images before uploading with a few lines of code. So, no more talk let's see how we can easily crop images in our application.

Table of Contents

  1. Setup Controller
  2. Setup View
  3. Setup Route
  4. Output

Setup Controller

So at first, we'll create a controller by firing the below command.

 php artisan make:controller ImageController

It'll create a controller under app/Http/Controllers called ImageController, open the file and below code in your controller. Look at the below source code.

app/Http/Controllers/ImageController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ImageController extends Controller
{
    public function index(): \Illuminate\Contracts\View\View|\Illuminate\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\Foundation\Application
    {
        return view('image_crop');
    }

    public function cropImage(Request $request): \Illuminate\Http\JsonResponse
    {
        $data = $request->image;

        list($type, $data) = explode(';', $data);
        list(, $data)      = explode(',', $data);

        $folder     = public_path() . "/upload/";
        if (!is_dir($folder)) {
            mkdir($folder, 0777, true);
        }
        $data       = base64_decode($data);
        $image_name = time().'.png';
        $path       = $folder . $image_name;

        file_put_contents($path, $data);

        return response()->json(['success'=>'done']);
    }
}

Setup View

Now we need to setup the blade file, so that we can show the result in a nice way.

resources/views/image_crop.blade.php
<html lang="en">
<head>
    <title>Laravel - jquery ajax crop image before upload using croppie plugins</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://foliotek.github.io/Croppie/croppie.css">
    <meta name="csrf-token" content="{{ csrf_token() }}">
</head>

<body>
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">Laravel crop image before upload using croppie plugins</div>
        <div class="panel-body">


            <div class="row">
                <div class="col-md-4 text-center">
                    <div id="upload-demo" style="width:350px"></div>
                </div>
                <div class="col-md-4" style="padding-top:30px;">
                    <strong>Select Image:</strong>
                    <br/>
                    <input type="file" id="upload">
                    <br/>
                    <button class="btn btn-success upload-result">Upload Image</button>
                </div>


                <div class="col-md-4" style="">
                    <div id="upload-demo-i"
                         style="background:#e1e1e1;width:300px;padding:30px;height:300px;margin-top:30px"></div>
                </div>
            </div>


        </div>
    </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://foliotek.github.io/Croppie/croppie.js"></script>

<script>
    $(document).ready(function (){
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });

        $uploadCrop = $('#upload-demo').croppie({
            enableExif: true,
            viewport: {
                width: 200,
                height: 200,
                type: 'circle'
            },
            boundary: {
                width: 300,
                height: 300
            }
        });

        $(document).on('change','#upload', function () {
            var reader = new FileReader();
            reader.onload = function (e) {
                $uploadCrop.croppie('bind', {
                    url: e.target.result
                }).then(function () {
                    console.log('jQuery bind complete');
                });
            }
            reader.readAsDataURL(this.files[0]);
        });


        $(document).on('click','.upload-result', function (ev) {
            $uploadCrop.croppie('result', {
                type: 'canvas',
                size: 'viewport'
            }).then(function (resp) {
                $.ajax({
                    url: "{{ route('image.crop') }}",
                    type: "POST",
                    data: {"image": resp},
                    success: function (data) {
                        let html = '<img src="' + resp + '" />';
                        $("#upload-demo-i").html(html);
                        alert('image uploaded');
                    }
                });
            });
        });
    });
</script>
</body>
</html>

Setup Route

Put the below route in the web.php file.

routes/web.php
Route::get('image-crop', [\App\Http\Controllers\ImageController::class,'index']);
Route::post('image-crop', [\App\Http\Controllers\ImageController::class,'cropImage'])->name('image.crop');

Output

Now it's the time to check the output. Go to localhost:8000/image-crop, and you'll find the below output.

Now if you upload an image and click on “Upload Image”, you'll get the below alert saying "Image Uploaded".

That's it for today. I hope it'll be helpful in upcoming project. You can also download this source code from GitHub. Thanks for reading. 🙂