ホームページ > バックエンド開発 > PHPチュートリアル > jQuery プラグイン Croppic + Intervention Image を使用して、Laravel 5 で画像のアップロードとトリミングを実装します。

jQuery プラグイン Croppic + Intervention Image を使用して、Laravel 5 で画像のアップロードとトリミングを実装します。

WBOY
リリース: 2016-06-23 13:13:43
オリジナル
1305 人が閲覧しました

1. 概要

多くの場合、ユーザー アバター用の画像アップロード コンポーネントを作成し、トリミング機能を実装する必要があります。各 Web サイトのレイアウトには独自のカスタム サイズがあり、その結果、サーバー上で画像がトリミングされ、画像の歪みが発生する可能性があります。このうち、私はクライアント側で画像を編集することを好みます。最近、この機能を簡単に実現できる jQuery プラグインを見つけました。この jQuery プラグインは Croppic です。

これは、Twitter、Facebook、または LinkedIn のユーザー アバター コンポーネントと同じように機能します。まず、ユーザーは操作する必要がある画像を選択し、適切だと感じたら、スライドとズームのオプションが提供されます。切り抜きボタンをクリックするだけです。とても簡単ではないでしょうか。

Croppic は次のように動作します:

  • ブラウザウィンドウで画像を選択し、サーバーにアップロードします
  • サーバーはアップロードしたばかりの画像へのリンクを返し、Croppic はこのリンクを通じて画像をレンダリングします
  • ユーザーはスライドできます画像をズームし、切り抜きボタンをクリックすると、画像データがサーバーに送信されます
  • サーバーは、画像の元のリンクと切り抜きの詳細: x 座標、y 座標、切り抜き幅、高さ、角度を受け取ります
  • サーバーはトリミングの詳細データを使用して画像を処理し、成功した応答をクライアントに送信します
  • 場合 プロセス全体でエラーが発生した場合、エラー メッセージを含むダイアログ ボックスがポップアップ表示されます
  • トリミングが成功した後、最終的な画像がユーザーの Croppic ボックスに表示されます
  • ユーザーは閉じるボタンをクリックして、プロセス全体を再実行できます

このチュートリアルでは、サーバー側の画像処理に Intervention Image 拡張パッケージを使用します。

注: このチュートリアルの完全なコードは Github にあります: https://github.com/codingo-me/laravel-croppic

2. Laravel プロジェクトをインストールして構成します

続行する前に必須このチュートリアルでは、まず Laravel プロジェクトの Croppic を作成し (既に作成されているものはスキップします)、次の設定を .env に追加します:

URL=http://croppic.dev/UPLOAD_PATH=/var/www/croppic/public/uploads/
ログイン後にコピー

注: 上記のドメイン名とパスは、特定の状況に応じて変更する必要があります。 。

介入/イメージがインストールされていない場合は、このチュートリアルを参照してください: Laravel 5 に介入イメージを統合して、イメージを作成、変更、圧縮する

3. Croppic オプション

JS オプション配列を通じて設定できます。 , Croppic は組み込みモーダルとして表示でき、カスタム データをバックエンドに渡したり、拡大縮小/回転係数を定義したり、画像出力要素を定義したり、アップロード ボタンをカスタマイズしたりできます。

FileReader API を介してクライアント側で画像のアップロードを開始することができます。これにより、上記の Croppic の動作方法の最初の 2 つの手順をスキップできますが、この解決策には欠点があります。一部のブラウザーは FileReader API をサポートしていません。

この例では、アップロードと切り抜き URL を定義し、切り抜きの幅と高さをバックエンドに手動で送信します。

var eyeCandy = $('#cropContainerEyecandy');var croppedOptions = {    uploadUrl: 'upload',    cropUrl: 'crop',    cropData:{        'width' : eyeCandy.width(),        'height': eyeCandy.height()    }};var cropperBox = new Croppic('cropContainerEyecandy', croppedOptions);
ログイン後にコピー

eyeCandy 変数タグは Croppic DOM 要素をレンダリングします CroppedOptions 設定では、jQuery を使用してeyeCandy 要素のサイズ。ここでサイズを計算する必要があります。これは、フロントエンドで Bootstrap グリッドを使用しているため、ウィンドウが変わると幅と高さが変わります。

4. フロントエンド

上で述べたように、Bootstrap を使用し、Croppic 公式 Web サイトからカスタム スタイル (home.blade.php) をダウンロードしました:

<!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⊂=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>
ログイン後にコピー

5. 3 つ必要です。ルート 、ホームページ用、投稿リクエストのアップロード用、および投稿リクエストのトリミング用の 1 つ:
<?phpRoute::get('/', 'CropController@getHome');Route::post('upload', 'CropController@postUpload');Route::post('crop', 'CropController@postCrop');
ログイン後にコピー

過去の経験に基づいて、Laravel が CSRF トークン エラーをスローすることがわかっているため、CSRF ミドルウェアで操作をトリミングしてアップロードします。

<?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;class VerifyCsrfToken extends BaseVerifier{    /**     * The URIs that should be excluded from CSRF verification.     *     * @var array     */    protected $except = [        'upload',        'crop'    ];}
ログイン後にコピー

6. バックエンド ロジック

画像モデルと移行ファイル

ここでは、画像のアップロードを追跡するためにデータベースを使用します。通常、画像とユーザーの間に関連付けが確立されます。ユーザーがその写真に関連付けられるようにします。

<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;class Image extends Model{    protected $table = 'images';    public static $rules = [        'img' => 'required|mimes:png,gif,jpeg,jpg,bmp'    ];    public static $messages = [        'img.mimes' => 'Uploaded file is not in image format',        'img.required' => 'Image is required'    ];}
ログイン後にコピー

通常、私はモデルクラスを別のディレクトリ app/Models に置くことに慣れています。

以下は、イメージ テーブルを作成するための移行ファイルです:

<?phpuse Illuminate\Database\Schema\Blueprint;use Illuminate\Database\Migrations\Migration;class CreateImages extends Migration{    /** * Run the migrations. * * @return void */    public function up()    {        Schema::create('images', function (Blueprint $table) {            $table->increments('id');            $table->text('original_name');            $table->text('filename');            $table->timestamps();        });    }    /** * Reverse the migrations. * * @return void */    public function down()    {        Schema::drop('images');    }}
ログイン後にコピー

新しいデータベースとデータベース ユーザーを作成し、.env 内の対応するオプションに構成と資格情報を設定する必要があります。移行コマンドを実行できます: php 職人移行。

画像ロジックのアップロード

このメソッドは、ユーザーがブラウザ ダイアログから画像を選択した直後に呼び出されます:

public function postUpload(){        $form_data = Input::all();        $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);        $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);}
ログイン後にコピー

まず、画像モデルの検証配列を使用して入力を検証し、画像形式を指定して宣言します。画像が必須であることを確認します。画像サイズなどの他の制約を追加することもできます。

検証が失敗した場合、エラー応答がバックグラウンドで送信され、Croppic はエラー ダイアログ ボックスもポップアップ表示します。

注: ネイティブのポップアップ ボックスは非常に見苦しいので、私は常に SweetAlert を使用します。SweetAlert を使用するには、croppic.js ファイルでアラートを検索し、行を sweetAlert("Oops..." に変更します)。 , response.message, 'error'); もちろん、SweetAlert 関連の css ファイルと js ファイルを HTML に導入する必要もあります。

我们使用 sanitize 和 createUniqueFilename 方法创建服务器端文件名,通常我还会创建 ImageRepository 并将所有所有方法放置到其中,但是这种方式更简单:

private function sanitize($string, $force_lowercase = true, $anal = false){        $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",            "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",            "&acirc;€”", "&acirc;€“", ",", "<", ".", ">", "/", "?");        $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;}
ログイン後にコピー

创建完独立的文件名后,我们使用Intervention Image提供的 ImageManger 来保存上传的图片。从上传方法返回的响应中Croppic需要如下字段:保存图片的 status 、 url 、 width 和 height 。

裁剪图片逻辑

用户点击裁剪按钮后,Croppic会将用户数据发送到后端路由以便对图片执行裁剪。到这里,你应该看到了,Croppic不做任何实际裁剪工作:-),它只负责发送x/y坐标以及裁剪的宽度和高度数据,具体的裁剪实现逻辑还需要在后台编写。Croppic项目为此提供了一些相关的php脚本,但这里我们仍然选择使用Intervention Image扩展包提供的方法:

public function postCrop(){        $form_data = Input::all();        $image_url = $form_data['imgUrl'];        // resized sizes        $imgW = $form_data['imgW'];        $imgH = $form_data['imgH'];        // offsets        $imgY1 = $form_data['imgY1'];        $imgX1 = $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, $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);}
ログイン後にコピー

完整的控制器 CropController 看上去应该是这样的:

<?phpnamespace 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()    {        return view('home');    }    public function postUpload()    {        $form_data = Input::all();        $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);        $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);    }    public function postCrop()    {        $form_data = Input::all();        $image_url = $form_data['imgUrl'];        // resized sizes        $imgW = $form_data['imgW'];        $imgH = $form_data['imgH'];        // offsets        $imgY1 = $form_data['imgY1'];        $imgX1 = $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, $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)    {        $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",            "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",            "&acirc;€”", "&acirc;€“", ",", "<", ".", ">", "/", "?");        $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;    }}
ログイン後にコピー

如果操作成功,后台会返回裁剪后的图片链接,然后Croppic根据此链接显示新的图片。

声明:本文为译文,原文链接: https://tuts.codingo.me/upload-and-edit-image-using-croppic-jquery-plugin

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート