ユーザー登録が噛んでくるシステムを開発していると、ユーザーが自身の画像を
アップロード出来て アバター画像に出来る様な機能はホボ実装されています。

しかし、アップロードしてユーザーが自分の好きなように画像のCropping(切り抜き)が
出来る機能はどうでしょうか?

TwitterやFacebook、Google等のサービスには画像のCropping機能が実装されていますが、
全体を通して見ると まだまだ多くない印象を受けます。

今回はJqueryプラグインの「Cropper」使って、画像の切り抜き機能の説明をします。
( * Cropper には jqueryに依存していないエディション、「CropperJS」も用意されています )

Cropper
 

画像がPOSTされた後のサーバー側の処理は、
PHPの「Lumenフレームワーク」+ 画像処理のライブラリ「Intervention Image」を使っています。
また、Laravelフレームワークでも動作可能です。
( * 今回はアップロードの部分は割愛しています  )


html側のコード

* ライブラリ

<!-- CDN -->
<!-- CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropper/1.0.0/cropper.min.css" rel="stylesheet" type="text/css" media="all"/>

<!-- JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/1.0.0/cropper.min.js"></script>


* 必要最低限のhtmlコードしか書いていないので、短くなっています。( * bootstrapとfont-awesomeを使用 )

<h3><i class="fa fa-crop"></i> cropperのデモ </h3>
<!-- 切り抜きボタン -->
<a id="getData" class="btn btn-primary">Get Data</a>
<br><br>
<div class="cropper-example-1">
  <!-- bladeテンプレートを使用していれば asset()や url() 関数が使えます -->
  <img id="img" class="img-responsive" src="./img/art.jpg" alt="">
</div>


* 初期設定

<script type="text/javascript">
// init
// class='cropper-example-1のimgタグに適用'
var $image = $('.cropper-example-1 > img'),replaced;

//crop options
// id='imgに適用'
$('#img').cropper({
  aspectRatio: 4 / 4 // ここでアスペクト比の調整 ワイド画面にしたい場合は 16 / 9

  });
</script>


* 上記のコードを書いたプレビュー画面

javascript側のコード

ここでボタンを押した時のPOST処理をしています。

// getDataボタンが押された時の処理
$('#getData').on('click', function(){

   // crop のデータを取得
   var data = $('#img').cropper('getData');

   // 切り抜きした画像のデータ
   // このデータを元にして画像の切り抜きが行われます
   var image = {
     width: Math.round(data.width),
     height: Math.round(data.height),
     x: Math.round(data.x),
     y: Math.round(data.y),
     _token: 'jf89ajtr234534829057835wjLA-SF_d8Z' // csrf用
    };

   // post 処理
   $.post('/cropper', image, function(res){
     // 成功すれば trueと表示されます
     console.log(res);
   });

});

 

サーバー側の処理

// app/routes.php
use Illuminate\Http\Request;
use Intervention\Image\ImageManagerStatic as Image;

$app->post('/cropper', function(Request $request){

  $str =  str_random(7);

  $crop =  value(function() use ($request, $str) {

              // Laravelの場合は public_path()ヘルパー関数、Facadeが使えます
              $image = Image::make('../public/img/art.jpg')
                      ->crop(
                             $request->get('width'),
                             $request->get('height'),
                             $request->get('x'),
                             $request->get('y')
                           )
                      ->resize(256,256) // 256 * 256にリサイズ
                      // 画像の保存
                      ->save('../public/img/'. $str . '.jpg')
                      ->resize(128,128) //サムネイル用にリサイズ
                      ->save('../public/img/'. $str . '_t' . '.jpg');

                      // 必要があれば元のファイルも消す
                      /* Lumenの場合は bootstrap/app.phpに以下のコードを追加
                      * class_alias('Illuminate\Support\Facades\File', 'File');
                      */
                      // \File::delete('Your image File);

                      return $image ?: false;

              });

  return $crop ? ['response' =>  true, 'img' => $str . '.jpg']
               : ['response' => false];

});


実際に切り抜きした画像  

* サムネ用も含めて二種類

Summary

今回は筆者自身もCroppingのサンプルアプリを作ってみましたが、
思っていた以上に時間を掛けずに出来ました。

Cropperのライブラリはシンプルに使用出来るのにも関わらず、
高機能なので 画像切り抜き機能の実装の際には候補に入れても問題ないと思います。

気になった人はCropperをチェックしてみてください!

 

この記事のカテゴリ

プログラミング

この記事のタグ

jsライブラリー , Lumen , Laravel

Socialシェアボタン

スポンサーリンク