Brython - FileReaderを使ってFlaskで画像を読み込み、アップロードする方法

2018-07-31 07:25:51 1258

はじめに

めっっっっっちゃハマったのでメモ。

まだよくわからないところがあるけど、とにかくBrythonだけですべての作業が完結できたのでハッピー。

html側


index.html
<input id="upload_image" class="form-control" type="file" accept="image/*">

id="upload_image"が必要です。まぁなんでもいいけど。

とりあえずフォーム作っとけばおk

brython側

html、pyどちらに書いてもおk
brython.py
from browser import window, alert, ajax
from javascript import JSConstructor
def upload_image():
global reader
jq = window.jQuery
file = jq('#upload_image').prop('files')[0]
file_reader = JSConstructor(window.FileReader)
reader = file_reader()
reader.onload = upload
f = reader.readAsDataURL(file)

def upload():
get_req = lambda req: log(req.text)
Ajax('/upload_image',{'data':reader.result}, get_req)

あとはFlask側で好きなように受けとったデータをくちゃくちゃすればいいと思います。

Ajax使ってます。

おまけ Flask側


flask.py
#省略
#PIL使ってます
@app.route('/upload_image', methods=['GET','POST'])
def upload_image():
filename = datetime.now().strftime('%Y_%m_%d_%H_%M_%S') + '.png'
image = request.form.get('data').split(',')[-1]
pil_img = Image.open(BytesIO(base64.b64decode(image)))
size = pil_img.size
pil_img.thumbnail((size[0]/2, size[1]/2), Image.ANTIALIAS)
pil_img.save(os.path.join(UPLOAD_FOLDER, filename),'PNG')
tag = '<img class="uploaded col-md-6" src="/static/images/%s">' % filename
return tag

追記

brython使えなくなった時のためのjQueryの方のメモ
jQuery.js
$('input[type=file]').change(function() {
var file = $(this).prop('files')[0];
var reader = new FileReader();
reader.onload = function() {
var img_src = reader.result;
$.ajax({
url: "/upload_image",
type:'POST',
data:{'data':img_src},
}).then(function(tag){
$("#content").val($("#content").val() + '\n' + tag);
$('input[type=file]').val('');
$('input[id=input]').focus();
$('#images').append(tag);
});
}
reader.readAsDataURL(file);
});

追記

改良版

改良版.py
def upload_image():
from javascript import JSConstructor
jq = window.jQuery
file = jq('#upload_image').prop('files')[0]
file_reader = JSConstructor(window.FileReader)
reader = file_reader()
reader.onload = lambda: upload(reader)
f = reader.readAsDataURL(file)

def upload(reader):
def get_image_tag(req):
document['content'].text += req.text
Ajax('/upload_image',{'data':reader.result}, get_image_tag)

globalを使わずにlambdaで済ました。やっぱこっちのがpythonっぽくていいわ。

関連記事