Use the JQuery plugin Croppic + intervention image in Laravel 5 for picture uploading and cropping

Source: Internet
Author: User

1. Overview

We often need to write the image upload component for the user's picture and implement the cropping function, and each site layout has its own custom size, which causes the picture to be cropped on the server, which is why I prefer to edit the picture on the client, And lately I've found a jquery plugin that makes it easy to do this, and this jquery plugin is croppic.

It works the same way as Twitter, Facebook or LinkedIn's avatar component, where the user chooses the picture that needs to be manipulated, then gives the user the swipe and zoom options, and clicks the crop button when it feels right, isn't it simple?

Croppic works in the following ways:

    • Upload a picture to the server in the browser window
    • The server returns a link to the image you just uploaded, croppic the link to render the picture
    • The user can swipe and zoom the picture, and when the Crop button is clicked, the image data is sent to the server
    • The server receives the original link to the picture and the cropping details: x-coordinate, y-coordinate, clipping width, height, angle
    • Server uses cropping details to process pictures after sending a successful response to the client
    • If an error occurs throughout the process, a dialog box with error messages pops up
    • After the crop is successful, the final picture is displayed in the user's Croppic box.
    • The user can click the Close button and then re-operate the entire process

In this tutorial we use the intervention Image extension package for server-side picture processing.

Note: The complete code for this tutorial can be found on GitHub: Https://github.com/codingo-me/laravel-croppic

2. Installation Configuration Laravel Project

Before continuing this tutorial, you need to create a Laravel project Croppic (skipped), and add the following configuration in. env:

url=http://croppic.dev/upload_path=/var/www/croppic/public/uploads/

Note: The above domain names and paths need to be modified according to your specific situation.

If Intervention/image is not installed, refer to this tutorial: integrating intervention Image in Laravel 5 to create, modify, and compress pictures

3. Croppic option

You can configure almost everything with the JS option array, Croppic can be displayed in the form of a built-in modal box, then you pass the custom data to the backend, define the zoom/rotate factor, define the image output element, or customize the upload button.

You can initialize the image upload via the FileReader API on the client side, so you can skip the first two steps of the Croppic working method above, but there is one drawback to this solution-some browsers do not support the FileReader API.

In this example we define the upload and crop URLs and then manually send the clipping width and height to the backend:

var Eyecandy = $ (' #cropContainerEyecandy '), var croppedoptions = {    uploadurl: ' Upload ',    cropurl: ' Crop ',    cropdata:{        ' width ': eyecandy.width (),        ' height ': eyecandy.height ()    }};var cropperbox = new Croppic (' Cropcontainereyecandy ', croppedoptions);

Eyecandy variable tags render croppic dom elements, in croppedoptions configuration we use jquery to get the dimensions of the Eyecandy element, where we need to calculate the dimensions, because we use the bootstrap grid on the front end, So the width and height will vary with the window.

4. Front-end

As mentioned above, we used bootstrap and downloaded the custom style (home.blade.php) directly from the Croppic website:

    
 
      Upload and edit images in Laravel using croppic jQuery plugin    
 
      
 
      
 
      
 
      
 
                          

Upload and edit images in Laravel using croppic jQuery plugin

Croppic is ideal for uploading profiles photos, or photos where you are require predefined Size/ratio .

5. Routing

We need 3 routes, one for the home page, one for uploading the post request, and one for cutting the POST request:

     

Based on past experience we know that Laravel will throw CSRF token errors, so we will exclude the cropping and uploading operations in the CSRF middleware:

      

6. Back-end Logic

image model and migration files

Here we use a database to save pictures to keep track of image uploads, often linking images and users, and associating users with images.

 
    ' Required|mimes:png,gif,jpeg,jpg,bmp '    ];    public static $messages = [        ' img.mimes ' = ' + ' uploaded file is not in image format ',        ' img.required ' = ' + ' image is required '    ];}

Usually I'm used to putting model classes in separate directory app/models.

Here is the migration file to create the images table:

 
    Increments (' id ');            $table->text (' original_name ');            $table->text (' filename ');            $table->timestamps ();        });    }    /** * Reverse the migrations. * * @return void *    /Public Function down ()    {        Schema::d rop (' images ');}    }

You need to create a new database and database user, then configure the configuration and credential information to the. env option, and then you can run the migration command after you complete these operations: PHP artisan migrate.

Upload picture Logic

This method is called immediately after the user selects the picture from the browser dialog box:

Public Function Postupload () {$form _data = Input::all ();        $validator = Validator::make ($form _data, Image:: $rules, Image:: $messages); if ($validator->fails ()) {return Response::json ([' status ' = ' error ', ' Me        Ssage ' = $validator->messages ()->first (),], 200);        } $photo = $form _data[' img ');        $original _name = $photo->getclientoriginalname ();        $original _name_without_ext = substr ($original _name, 0, strlen ($original _name)-4);        $filename = $this->sanitize ($original _name_without_ext);        $allowed _filename = $this->createuniquefilename ($filename); $filename _ext = $allowed _filename.        JPG ';        $manager = new Imagemanager ();        $image = $manager->make ($photo)->encode (' jpg ')->save (env (' Upload_path '). $filename _ext); if (! $image) {return Response::json ([' status ' = ' error ', ' message ' => ' Server error while uploading ',], 200);        } $database _image = new Image;        $database _image->filename = $allowed _filename;        $database _image->original_name = $original _name;        $database _image->save (); return Response::json ([' status ' = ' success ', ' url ' = + env (' URL '). ' uploads/'.  $filename _ext, ' width ' = $image->width (), ' height ' = $image->height ()], 200);}

First I validate the input using the validation array of the image model, where I specify the picture format and declare that the picture is required. You can also add other constraints, such as chip size.

If the validation fails, the background sends an error response, and croppic also pops up an error dialog box.

Note: The native pop-up box looks really ugly, so I always use Sweetalert, to use Sweetalert to search for alert in the Croppic.js file and replace the row with: Sweetalert ("Oops ...", Response.message, ' error '); Of course you also have to introduce Sweetalert related CSS and JS files in HTML.

We use the sanitize and Createuniquefilename methods to create a server-side file name, and I usually create the imagerepository and place all the methods in it, but this is easier:

Private Function sanitize ($string, $force _lowercase = true, $anal = False) {$strip = array ("~", "'", "!", "@", "#",  "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", "}", "\ \", "|", ";", ":", "\" "," ' "," ' ",        "'", "" "," "", "" – ","-"," â € "", "â €" ",", "," < ",". "," > ","/","? ");        $clean = Trim (Str_replace ($strip, "", Strip_tags ($string)));        $clean = preg_replace ('/\s+/', "-", $clean); $clean = ($anal)?        Preg_replace ("/[^a-za-z0-9]/", "", $clean): $clean;            Return ($force _lowercase)?                (Function_exists (' Mb_strtolower '))? Mb_strtolower ($clean, ' UTF-8 '): Strtolower ($clean): $clean;}        Private Function Createuniquefilename ($filename) {$upload _path = env (' Upload_path '); $full _image_path = $upload _path. $filename.        '. jpg '; if (file::exists ($full _image_path)) {//Generate token for image $image _token = substr(SHA1 (Mt_rand ()), 0, 5); Return $filename. '-' .        $image _token; } return $filename;}

After creating a separate file name, we use the imagemanger provided by intervention image to save the uploaded image. The following fields are required in the response returned from the Upload method Croppic: Save the status, URL, width, and height of the picture.

Crop picture Logic

When the user taps the Crop button, Croppic sends the user data to the back-end route to crop the picture. Here, you should see, croppic do not do any actual cropping work:-), it is only responsible for sending X/Y coordinates as well as clipping width and height data, the specific clipping implementation logic also needs to be written in the background. The Croppic project provides some relevant PHP scripts for this, but here we still choose to use the method provided by the intervention image extension package:

Public Function Postcrop () {$form _data = Input::all ();        $image _url = $form _data[' Imgurl ');        Resized sizes $imgW = $form _data[' IMGW '];        $imgH = $form _data[' imgh ');        Offsets $imgY 1 = $form _data[' imgY1 ');        $imgX 1 = $form _data[' imgX1 ');        Crop box $cropW = $form _data[' width ');        $cropH = $form _data[' height '];        Rotation angle $angle = $form _data[' rotation '];        $filename _array = explode ('/', $image _url);        $filename = $filename _array[sizeof ($filename _array)-1];        $manager = new Imagemanager ();        $image = $manager->make ($image _url);            $image->resize ($imgW, $imgH)->rotate (-$angle)->crop ($cropW, $cropH, $imgX 1, $imgY 1) ->save (env (' Upload_path '). ' cropped-'.        $FILENAME); if (! $image) {return Response::json ([' status ' = ' error ', ' message ' + ' S Erver error while uploading ',           ], 200); } return Response::json ([' status ' = ' success ', ' url ' = + env (' URL '). ' uploads/cropped-'. $filename], 200);}

The complete controller Cropcontroller should look like this:

   Fails ()) {return Response::json ([' status ' = ' error ', ' message ') = $valid        Ator->messages ()->first (),], 200);        } $photo = $form _data[' img ');        $original _name = $photo->getclientoriginalname ();        $original _name_without_ext = substr ($original _name, 0, strlen ($original _name)-4);        $filename = $this->sanitize ($original _name_without_ext);        $allowed _filename = $this->createuniquefilename ($filename); $filename _ext = $allowed _filename.        JPG ';        $manager = new Imagemanager ();        $image = $manager->make ($photo)->encode (' jpg ')->save (env (' Upload_path '). $filename _ext); if (! $image) {return Response::json ([' status ' = ' error ', ' message ' + ' S        Erver error while uploading ',], 200);        } $database _image = new Image;        $database _image->filename = $allowed _filename; $Database_image->original_name = $original _name;        $database _image->save (); return Response::json ([' status ' = ' success ', ' url ' = + env (' URL '). ' uploads/'.  $filename _ext, ' width ' = $image->width (), ' height ' = $image->height ()],    200);        Public Function Postcrop () {$form _data = Input::all ();        $image _url = $form _data[' Imgurl ');        Resized sizes $imgW = $form _data[' IMGW '];        $imgH = $form _data[' imgh ');        Offsets $imgY 1 = $form _data[' imgY1 ');        $imgX 1 = $form _data[' imgX1 ');        Crop box $cropW = $form _data[' width ');        $cropH = $form _data[' height '];        Rotation angle $angle = $form _data[' rotation '];        $filename _array = explode ('/', $image _url);        $filename = $filename _array[sizeof ($filename _array)-1];        $manager = new Imagemanager (); $image = $manager->make ($image _url);            $image->resize ($imgW, $imgH)->rotate (-$angle)->crop ($cropW, $cropH, $imgX 1, $imgY 1) ->save (env (' Upload_path '). ' cropped-'.        $FILENAME); if (! $image) {return Response::json ([' status ' = ' error ', ' message ' + ' S        Erver error while uploading ',], 200); } return Response::json ([' status ' = ' success ', ' url ' = + env (' URL '). ' uploads/cropped-'.    $filename], 200); The Private function sanitize ($string, $force _lowercase = true, $anal = False) {$strip = array ("~", "'", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", "}", "\", "|", ";", ":", "\" ",        "'", "'", "'", "" "," "", "" "," "-", "-", "â €", "â €" ",", "," < ",". "," > ","/","? ");        $clean = Trim (Str_replace ($strip, "", Strip_tags ($string)));    $clean = preg_replace ('/\s+/', "-", $clean);    $clean = ($anal)?        Preg_replace ("/[^a-za-z0-9]/", "", $clean): $clean;            Return ($force _lowercase)?                (Function_exists (' Mb_strtolower '))?    Mb_strtolower ($clean, ' UTF-8 '): Strtolower ($clean): $clean;        } Private Function Createuniquefilename ($filename) {$upload _path = env (' Upload_path '); $full _image_path = $upload _path. $filename.        '. jpg '; if (file::exists ($full _image_path)) {//Generate token for image $image _token = substr (s            HA1 (Mt_rand ()), 0, 5); Return $filename. '-' .        $image _token;    } return $filename; }}

If the operation succeeds, the background returns the cropped picture link, and Croppic displays the new picture based on the link.

Disclaimer: This article is translated, the original link: https://tuts.codingo.me/upload-and-edit-image-using-croppic-jquery-plugin

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.