LoginSignup
0
1

More than 1 year has passed since last update.

Cropper.jsで加工した画像をAjaxでLaravelに送り保存する。

Last updated at Posted at 2022-01-13

この記事では、Cropper.jsを利用し画像を加工したあとに、加工した画像をAjaxを通してLaravelに渡し、その画像を保存する方法を紹介します。

Cropper.jsは、ライブプレビューとカスタムアスペクト比をサポートしており、JavaScript / jQueryプラグインを画像のトリミングに利用するのに便利です。

事前準備

1. フォルダの作成

ファイルを保存する先のフォルダを作成します。

今回、コントローラで指定するフォルダは「storage/app/public/upload」です。

ファイルをアップロードして画像を切り取って保存を押すと、このフォルダに保存されます。

バックエンド側

2. ルーティング

次に下記のルーティングを設定してください。

routes/web.php

Route::get('image-cropper','ImageCropperController@index');
Route::post('image-cropper/upload','ImageCropperController@upload');

3. コントローラ

次に下記のようなコントローラを作成します。

app/Http/Controller/ImageCropperController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ImageCropperController extends Controller
{
   public function index()
   {
       return view('cropper');
   }
   public function upload(Request $request)
   {
       $folderPath = storage_path('app/public/upload/'); // 保存先のパス
       $image_parts = explode(";base64,", $request->image);
       $image_type_aux = explode("image/", $image_parts[0]); // ファイルの型を取り出す(今回は使わない)
       $image_type = $image_type_aux[1]; // ファイルの型を取り出す(今回は使わない)
       $image_base64 = base64_decode($image_parts[1]); // 画像データとして取り出す
       $file = $folderPath . uniqid() . '.png'; // 保存に使うファイル名
       file_put_contents($file, $image_base64); // ファイルを保存
       return response()->json(['success'=>'success']); // JSONでレスポンスを返す
   }
}

フロントエンド側

3. ビュー

最後にお待ちかねのビューを用意します。

ここにCropper.jsの処理も記述します。

resources/views/cropper.blade.php

<!DOCTYPE html>
<html>
<head>
   <title>Laravel Crop Image Before Upload using Cropper JS - LaravelCode</title>
   <meta name="_token" content="{{ csrf_token() }}">
   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" crossorigin="anonymous" />
   <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha256-WqU1JavFxSAMcLP2WIOI+GB2zWmShMI82mTpLDcqFUg=" crossorigin="anonymous"></script>
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.css" integrity="sha256-jKV9n9bkk/CTP8zbtEtnKaKf+ehRovOYeKoyfthwbC8=" crossorigin="anonymous" />
   <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.js" integrity="sha256-CgvH7sz3tHhkiVKh05kSUgG97YtzYNnWt6OXcmYzqHY=" crossorigin="anonymous"></script>
</head>
<style type="text/css">
img {
 display: block;
 max-width: 100%;
}
.preview {
 overflow: hidden;
 width: 160px; 
 height: 160px;
 margin: 10px;
 border: 1px solid red;
}
.modal-lg{
 max-width: 1000px !important;
}
</style>
<body>
<div class="container">
   <h1>Cropper.JSで加工した画像をAjaxでLaravelに送信</h1>
   <input type="file" name="image" class="image">
</div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="modalLabel" aria-hidden="true">
 <div class="modal-dialog modal-lg" role="document">
   <div class="modal-content">
     <div class="modal-header">
       <button type="button" class="close" data-dismiss="modal" aria-label="Close">
         <span aria-hidden="true">×</span>
       </button>
     </div>
     <div class="modal-body">
       <div class="img-container">
           <div class="row">
               <div class="col-md-8">
                   <img id="image" src="https://avatars0.githubusercontent.com/u/3456749">
               </div>
               <div class="col-md-4">
                   <div class="preview"></div>
               </div>
           </div>
       </div>
     </div>
     <div class="modal-footer">
       <button type="button" class="btn btn-secondary" data-dismiss="modal">キャンセル</button>
       <button type="button" class="btn btn-primary" id="crop">保存</button>
     </div>
   </div>
 </div>
</div>
</div>
</div>
<script>
var $modal = $('#modal');
var image = document.getElementById('image');
var cropper;

$("body").on("change", ".image", function(e){
   var files = e.target.files;
   var done = function (url) {
     image.src = url;
     $modal.modal('show');
   };
   var reader;
   var file;
   var url;
   if (files && files.length > 0) {
     file = files[0];
     if (URL) {
       done(URL.createObjectURL(file));
     } else if (FileReader) {
       reader = new FileReader();
       reader.onload = function (e) {
         done(reader.result);
       };
       reader.readAsDataURL(file);
     }
   }
});
$modal.on('shown.bs.modal', function () {
   cropper = new Cropper(image, {
      aspectRatio: 1,
      viewMode: 3,
      preview: '.preview'
   });
}).on('hidden.bs.modal', function () {
  cropper.destroy();
  cropper = null;
});
$("#crop").click(function(){
   canvas = cropper.getCroppedCanvas({
        width: 160,
        height: 160,
     });
   canvas.toBlob(function(blob) {
       url = URL.createObjectURL(blob);
       var reader = new FileReader();
        reader.readAsDataURL(blob); 
        reader.onloadend = function() {
           var base64data = reader.result;  
           $.ajax({
               type: "POST",
               dataType: "json",
               url: "image-cropper/upload",
               data: {'_token': $('meta[name="_token"]').attr('content'), 'image': base64data},
               success: function(data){
                   $modal.modal('hide');
                   alert("success upload image");
               }
             });
        }
   });
})
</script>
</body>
</html> 

最後に

以上の実装でAjaxを通してLaravelにCropper.jsで加工した画像を送れるはずです。

ぜひ試してみてください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1