JQueryとCroppieでトリミングした画像をサーバサイド【Python・Flask】にAjaxを使ってPOSTし、S3にアップロードするまでの実装手順を紹介していきます。
画像トリミング機能の流れ
今回のトリミング機能は以下の流れで処理していきます。今回の記事ではパート1として1〜4までの手順を記述し、5〜6はパート2として次回記事で紹介していきます。
- file inputから画像を選択
- 選択後、モーダル とcroppieのトリミング機能を表示
- トリミングしたい形でサイズと枠を合わせたら画像トリミングボタンをクリック
- 画像をトリミング処理
- トリミングされた画像をAjaxでサーバサイドへPOST
- サーバーサイド(python,flask)でトリミングした画像をAWS S3にアップロード
使用するライブラリ
・Croppie
Croppie – a javascript image cropper
Croppie uses canvas.drawImage(…) to manipulate images. Thus, images must obey the CORS policy. More info can be found here. Croppie is dependent on it’s container being visible when the bind method is called. This can be an issue when your croppie component is inside a modal that isn’t shown.
・Bootstrap Modal
Modal
Use Bootstrap’s JavaScript modal plugin to add dialogs to your site for lightboxes, user notifications, or completely custom content.
Croppieファイルをインストール
以下のGitHubページからcroppie.jsとcroppie.css をインストールし、プロジェクト内に設置します。Headタグ内に以下を記述。
Foliotek/Croppie
Bower: bower install croppie Npm: npm install croppie Download: croppie.js & croppie.css cdnjs.com provides croppie via cdn https://cdnjs.com/libraries/croppie https://cdnjs.cloudflare.com/ajax/libs/croppie/{version}/croppie.min.css https://cdnjs.cloudflare.com/ajax/libs/croppie/{version}/croppie.min.js Documentation First, thanks for contributing. This project is difficult to maintain with one person. Here’s a “checklist” of things to remember when contributing to croppie. Don’t forget to update the documentation.
<!-- Jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- croppie.css -->
<link href="{{ url_for('static', filename='css/croppie.css')}}" rel="stylesheet" type="text/css">
<script src="{{ url_for('static', filename='js/croppie.js')}}"></script>
<!-- BOOTSTRAP -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
ファイルinputを追加
最初に画像をアップロードするためHTMLのFile Inputを追加します。idにupload_imageを指定。このidは画像選択後、画像トリミング用のモーダル を表示させる際の発火用に使用します。
<div class="panel panel-default">
<div class="panel-body" align="left">
<h5><i class="far fa-images"></i>サークル画像アップロード</h5>
<div class="custom-file">
<input type="file" name="upload_image" id="upload_image" class="custom-file-input" accept="image/*" />
<label class="custom-file-label" for="customFile">Choose file</label>
</div>
</div>
</div>
bootstrapのmodalを追加
先述した通り、画像選択後、画像トリミング用のモーダル を表示させます。まず、bootstrapからmodalのコードをコピーアンドペーストで持ってきます。追加で必要なコードはアップロードした画像を表示させるためid=”image_demo”をmodal-body内に記述します。その下に画像トリミングとアップロードボタンを設置します。これで下準備が終了したので、続いてJQueryで画像トリミングの処理部分のコードを記述していきます。
<!-- #########Modal################################### -->
<div style="z-index: 3;" class="modal fade" id="uploadimageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">メディアを編集</h5>
</div>
<div class="modal-body">
<div id="image_demo" style="width:350px; margin-top:10px"></div>
<div class="col-md-4" style="padding-top:10px;">
<button class="btn btn-outline-success crop_image">画像をトリミング&アップロード</button>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" id="croppie_close" data-dismiss="modal">閉じる</button>
</div>
</div>
</div>
</div>
今回、レスポンシブにも対応させたいので、window.matchMediaを使用してデバイスごとにサイズを調整します。続いてcroppieの基本設定のコードを記述します。画像アップロード後、id=image_demoに表示された画像がトリミングの対象です。boundaryは画像のサイズ、viewportは内枠のサイズ。詳しくはcroppieのサイトをご参照ください。
Croppieの基本設定
#レスポンシブ対応
$(document).ready(function(){
if (window.matchMedia( '(min-width: 320px) and (max-width: 639px)' ).matches) {
viewportWidth = 270
viewportHeight = 170
boundaryWidth = 290
boundaryHeight = 180
} else if (window.matchMedia( '(min-width: 640px) and (max-width: 1023px)' ).matches) {
viewportWidth = 460
viewportHeight = 290
boundaryWidth = 480
boundaryHeight = 290
} else {
viewportWidth = 650
viewportHeight = 400
boundaryWidth = 700
boundaryHeight = 400
}
#croppieの初期設定
$image_crop = $('#image_demo').croppie({
enableExif: true,
viewport: {
width: viewportWidth,
height:viewportHeight,
type:'square' //circle
},
boundary: {
width: boundaryWidth,
height: boundaryHeight
}
});
画像選択後モーダル を表示させる
画像選択されたら、画像をバインドしcroppieに画像URLをセットしてあげます。同時にbootstrapのモーダル を表示させます。これで、モーダル が表示されcroppieの初期化は終了です。
$('#upload_image').on('change', function(){
var reader = new FileReader();
reader.onload = function (event) {
$image_crop.croppie('bind', {
url: event.target.result
}).then(function(){
console.log('jQuery bind complete');
});
}
reader.readAsDataURL(this.files[0]);
$('#uploadimageModal').addClass('show');
$('#uploadimageModal').css('display','block');
});
ボタンをクリックしたら画像をトリミングする
画像をトリミング&アップロードボタンをクリックすると画像がトリミングされた画像データを取得できるので、Ajaxでサーバーサイドにデータを渡します。最後に画像トリミングが終了したらモーダル を閉じるためのコードを記述します。サーバサイドに画像データを渡してS3にアップロードする手順については次回記事で記述していきます。
#ボタンをクリックしたら
$('.crop_image').click(function(event){
$image_crop.croppie('result', {
type: 'canvas',
size: 'viewport'
}).then(function(response){
// console.log(response)
$.ajax({
url:"/image",
type: "POST",
data:{"image": response},
success:function(data) {
パート②で記述
}
});
})
});
#モーダル を閉じる
$(document).ready(function(){
$('#croppie_close').click(function() {
$('#uploadimageModal').removeClass('show');
$('#uploadimageModal').css('display','none');
$('input[type=file]').val('');
});
});
});
パート2の記事ではサーバサイド側の処理を以下の二つに分けて記述していきます。
- トリミングされた画像をAjaxでサーバサイドへPOST
- サーバーサイド(python,flask)でトリミングした画像をAWS S3にアップロード