今回はJQueryとCroppieでトリミングした画像をサーバサイド【Python・Flask】にAjaxを使ってPOSTし、S3にアップロードするまでの実装手順を紹介していきます。
画像トリミング機能実装の流れ
トリミング機能の実装の流れは以下のようになります。①の記事では1から4まで説明をしたので今回の記事では5と6について解説していきます。①の記事はこちらになります。
【Python・Flask】JQueryとCroppieで画像をトリミングしてS3にアップロードする①
JQueryとCroppieでトリミングした画像をサーバサイド【Python・Flask】にAjaxを使ってPOSTし、S3にアップロードするまでの実装手順を紹介していきます。 今回のトリミング機能は以下の流れで処理していきます。今回の記事ではパート1として1〜4までの手順を記述し、5〜6はパート2として次回記事で紹介していきます。 file inputから画像を選択 選択後、モーダル とcroppieのトリミング機能を表示 トリミングしたい形でサイズと枠を合わせたら画像トリミングボタンをクリック 画像をトリミング処理 トリミングされた画像をAjaxでサーバサイドへPOST サーバーサイド(python,flask)でトリミングした画像をAWS S3にアップロード 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.
- file inputから画像を選択
- 選択後、モーダル とcroppieのトリミング機能を表示
- トリミングしたい形でサイズと枠を合わせたら画像トリミングボタンをクリック
- 画像をトリミング処理
- トリミングされた画像をAjaxでサーバサイドへPOST
- サーバーサイド(python,flask)側でトリミングした画像をAWS S3にアップロード
トリミングされた画像をAjaxでサーバサイドへPOST
前回は画像のトリミング処理までのコードを記述しました。今回、トリミングした画像をAjaxでサーバーサイド側にPOSTする部分のコードから記述していきたいと思います。まずはこちらのコードの「パート②で記述」の部分から始めていきます。
#ボタンをクリックしたら
$('.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('');
});
});
});
Ajaxのコードですが、POST先のURLとして/image、送信タイプをPOST,送信するdata(トリミング処理した画像)をimageという名でJSON形式で送ります。success:function(data) { 以降のコードはPOST送信が成功したときに処理されます。送信後はモーダル 画面を削除してinput image内のvalueを空にします。
$.ajax({
url:"/image",
type: "POST",
data:{"image": response},
success:function(data) {
$('#uploadimageModal').removeClass('show');
$('#uploadimageModal').css('display','none');
$('input[type=file]').val(''); //inputファイルを空にする。
$('#ajax_account_image').attr('src',data.image);
setTimeout(function(){
$("#overlay").fadeOut(300);
},500);
}
});
サーバーサイド(python,flask)側でトリミングした画像をAWS S3にアップロード
続いてBytesIOに受け取ったバイナリの画像データを渡してあげます。画像名はユニークな名前で保存したいので、add_profile_pic()で処理してあげます。
from PIL import Image
import random
import boto3
import base64
from io import BytesIO
s3 = boto3.client(
's3',
aws_access_key_id=app.config['AWS_ACCESS_KEY_ID'],
aws_secret_access_key=app.config['AWS_SECRET_ACCESS_KEY']
)
@users.route('/image',methods=['POST'])
@login_required
def image():
if request.method == 'POST':
enc_data = request.form['image']
dec_data = base64.b64decode(enc_data.split(',')[1]) # 環境依存の様(","で区切って本体をdecode)
dec_img = Image.open(BytesIO(dec_data))
image = add_profile_pic(dec_img)
image = "{}png".format(image)
s3_resource = boto3.resource('s3')
my_bucket = s3_resource.Bucket(app.config['AWS_BUCKET'])
my_bucket.Object(image).put(Body=BytesIO(dec_data))
image_url = 'https://'+str(app.config['AWS_BUCKET'])+'.s3-ap-northeast-1.amazonaws.com/{}'
image_url = image_url.format(image)
current_user.profile_image = image_url
db.session.commit()
return jsonify({'image': image_url})
def add_profile_pic(pic_upload):
filename = pic_upload.filename
ext_type = filename.split('.')[-1]
suffix = datetime.now().strftime("%y%m%d_%H%M%S")
s = 'abcdefghijklmnopqrstuvwxyz'
result = "".join([random.choice(s) for x in range(10)])
storage_filename = str(suffix)+str(result)+'.'+ext_type
return storage_filename
以上がJQueryとCroppieで画像をトリミングしてS3にアップロードするのに必要なコードになります。これで、実際にinput fileで画像を選択してあげると下の画像のようにトリミング用のモーダル 画面が表示されます。「画像をトリミングボタン」をクリックするとトリミングされた画像がサーバーサイド側に送信され、AWSのs3にアップロードされます。
今回のコードの課題点としてはエラーハンドリングの処理が出来ていない点とdecodeとencodeの知識が不足していたので再確認する必要がありそうです。