Sử dụng thư viện javascript để crop image trong laravel

Hôm nay mình sẽ hướng dẫn các bạn dùng thư viện Croppic để giúp người dùng crop image theo kích thước quy định sẵn. Mục đích của việc này là để các image có cùng kích thước, và người dùng có thể control được hình ảnh để phù hợp với kích thước hình ảnh của website. Demo của nó sẽ như vậy: Đầu tiên, hãy vào trang chủ của nó để xem những option và setting của thư viện này là gì. Và đây là đoạn code của nó:

HTML:
<div id="yourId"></div>
CSS:
#yourId {
			width: 200px;
			height: 150px;
			position:relative; /* or fixed or absolute */
		}
YS:
var cropperOptions = {
			uploadUrl:'path_to_your_image_proccessing_file.php',//route để upload hình ảnh.
            uploadData:{ //dữ liệu khác mà bạn muôn truyền qua để xử lý cho việc upload hình ảnh
				"dummyData":1,
				"dummyData2":"text"
			},
            cropUrl:'path_to_your_image_cropping_file.php' //route để xử lý crop hình ảnh
            cropData:{//dữ liệu khác mà bạn muôn truyền qua để xử lý cho việc crop hình ảnh
				"dummyData":1,
				"dummyData2":"text"
			},
            loadPicture:'path-to-your-image', //load 1 image trước khi thực hiện upload và crop hình ảnh, khi load image trước thì nếu bạn có bấm close ở khung upload nó vẫn hiện lại image này.
            ....
}
var cropperHeader = new Croppic('yourId', option);

Các bạn có thể vào trang chủ của croppic để tìm hiểu thêm về các option và setting của nó nhé.

Bài viết này mình sẽ dùng nó tích hợp vào laravel. Đầu tiên, bạn vào file .env để khai báo thư mục upload nhé, bạn không nhất thiết phải khai báo trong env, bạn có thể khai báo nó trong config rồi dùng asset('path') cũng được.

URL=http://croppic.dev/
UPLOAD_PATH=/var/www/html/tuts/croppic/public/uploads/

Tiếp theo bạn cần cài đặt thư viện này để hỗ trợ cho việc crop image composer require intervention/image

Sau đó bạn khai báo 2 route để dùng cho việc xử lý upload và crop hình ảnh, và đương nhiên là có 1 route để hiện form upload.

Route::get('/', '[email protected]');
//route xử lý upload và crop image
Route::post('upload', '[email protected]');
Route::post('crop', '[email protected]');

Như khai báo route thì trong controller CropController mình sẽ có 3 method như sau:

<?php

namespace App\Http\Controllers;

use App\Models\Image;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Response;
use Intervention\Image\ImageManager;
use Illuminate\Support\Facades\File;

class CropController extends Controller{

    public function getHome() // method này để render view upload
    {
        return view('home');
    }

    public function postUpload() //method này để xử lý upload image
    {
        $form_data = Input::all();

        //hiện tại mình validate trong controller, bạn có thể validate trong Request cũng được nhé
        $validator = Validator::make($form_data, Image::$rules, Image::$messages);

        if ($validator->fails()) {

            return Response::json([
                'status' => 'error',
                'message' => $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);//mã hóa tên file, mình sẽ comment nó ở phần dưới
        $allowed_filename = $this->createUniqueFilename( $filename ); //tạo ra file name đảm bảo file name không trùng lặp

        $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);

        }

//đây là đoạn xử lý để lưu image vào trong database, nếu image của bạn không có table riêng thì bỏ qua đoạn này nhé
        $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()//method này để xử lý crop image
    {
        $form_data = Input::all();
        $image_url = $form_data['imgUrl'];

        // resized sizes: with và height image
        $imgW = $form_data['imgW'];
        $imgH = $form_data['imgH'];
        // offsets: vị trí của image
        $imgY1 = $form_data['imgY1'];
        $imgX1 = $form_data['imgX1'];
        // crop box: with và height crop
        $cropW = $form_data['width'];
        $cropH = $form_data['height'];
        // rotation angle //image xoay bao nhiêu độ
        $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, $imgX1, $imgY1)
            ->save(env('UPLOAD_PATH') . 'cropped-' . $filename);

        if( !$image) {

            return Response::json([
                'status' => 'error',
                'message' => 'Server error while uploading',
            ], 200);

        }

        return Response::json([
            'status' => 'success',
            'url' => env('URL') . 'uploads/cropped-' . $filename
        ], 200);

    }


    private function sanitize($string, $force_lowercase = true, $anal = false)
    {//method này để mã hóa image, chuyển những ký tự đặt biệt về ký tự "-" hay ""
        $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",
            "}", "\\", "|", ";", ":", "\"", "'", "&#8216;", "&#8217;", "&#8220;", "&#8221;", "&#8211;", "&#8212;",
            "—", "–", ",", "<", ".", ">", "/", "?");
        $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 )
    {//tạo ra image unique
        $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;
    }
}

Đây là phần xử lý chính của bài nên bạn tìm hiểu kỹ nó nhé. Và cuối cùng là phần view

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload and edit images in Laravel using Croppic jQuery plugin</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="plugins/croppic/assets/css/main.css"/>
    <link rel="stylesheet" href="plugins/croppic/assets/css/croppic.css"/>

    <link href='http://fonts.googleapis.com/css?family=Lato:300,400,900' rel='stylesheet' type='text/css'>
    <link href='http://fonts.googleapis.com/css?family=Mrs+Sheppards&subset=latin,latin-ext' rel='stylesheet' type='text/css'>

</head>
<body>

<div class="container">
    <div class="row margin-bottom-40">
        <div class="col-md-12">
            <h1>Upload and edit images in Laravel using Croppic jQuery plugin</h1>
        </div>
    </div>

    <div class="row margin-bottom-40">
        <div class=" col-md-3">
            <div id="cropContainerEyecandy"></div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-12">
            <p><a href="http://www.croppic.net/" target="_blank">Croppic</a> is ideal for uploading profile photos,
        or photos where you require predefined size/ratio.</p>
        </div>
    </div>
</div>
<script src=" https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="plugins/croppic/croppic.min.js"></script>
<script>
    var eyeCandy = $('#cropContainerEyecandy');
    var croppedOptions = {
        uploadUrl: 'upload',
        cropUrl: 'crop',
        cropData:{
            'width' : eyeCandy.width(),
            'height': eyeCandy.height()
        }
    };
    var cropperBox = new Croppic('cropContainerEyecandy', croppedOptions);
</script>
</body>
</html>

vậy là bạn có thể xử lý được module crop image rồi nhé, bạn có thể tìm hiểu kỹ hơn ở đây: https://tuts.codingo.me/upload-and-edit-image-using-croppic-jquery-plugin Chúc bạn thành công, nếu có thắc mắc gì bạn comment ở dưới nhé. Nguồn:


All Rights Reserved