ドラッグ&ドロップでアップロードする画像を指定し、画像をサーバに送信します。
サーバは python の flask を使って作成します。
※テンプレートファイルが html と解釈されてしまっています。
ファイル構成
.
├── image_controller.py
├── image_processor.py
├── image_server.py
└── template
├── index.html
└── upload.html
サーバ本体: image_server.py
from flask import Flask, render_template
from image_controller import ImageController
gconfig = {
'port': 5001,
'template': {
'folder': 'template',
},
'index': {
'url': '/intra/test/upload_image/',
'template': 'index.html',
},
'upload': {
'url': '/intra/test/upload_image/upload',
'template': 'upload.html',
}
}
app = Flask(__name__, template_folder=gconfig['template']['folder'])
@app.route(gconfig['index']['url'], methods=["e;GET"e;])
def view_index():
html = render_template(gconfig['index']['template'])
return html
@app.route(gconfig['upload']['url'], methods=["e;POST"e;])
def view_upload():
ctrl = ImageController(gconfig)
resp_obj = ctrl.upload()
html = render_template(
gconfig['upload']['template'],
title=resp_obj['title'],
image_type=resp_obj['image_type'],
image_base64=resp_obj['image_base64']
)
return html
def main():
app.run(port=gconfig['port'], host='0.0.0.0')
return 1
if __name__ == '__main__':
res = main()
exit(res)
コントローラ: image_controller.py
from flask import request
from image_processor import ImageProcessor
class ImageController:
def __init__(self, config):
self.config = config
self.processor = ImageProcessor(config)
def upload(self):
params = {}
params['title'] = request.form.get('title', '')
params['image'] = request.files.get('image').stream.read()
#print(params['image'])
resp_obj = self.processor.upload(params)
return resp_obj
処理: image_processor.py
import io
import base64
import imghdr
class ImageProcessor:
def __init__(self, config):
self.config = config
def upload(self, params):
image_base64 = base64.b64encode(params['image']).decode('utf-8')
image_type = imghdr.what(io.BytesIO(params['image']))
obj = {
'title': params['title'],
'image_type': f'image/{image_type}',
'image_base64': image_base64,
}
return obj
画像アップロード画面テンプレート: index.html
<!DOCTYPE html>
<html lang="e;ja"e;>
<head>
<title>drag & drop image</title>
</head>
<body>
<form method="e;POST"e; action="e;upload"e; enctype="e;multipart/form-data"e;>
<input id="e;id_input"e; type="e;file"e; name="e;image"e; accept="e;image/*"e; hidden>
<input id="e;id_title"e; type="e;text"e; name="e;title"e; size="e;40"e;>
<button id="e;id_remove"e; type="e;button"e;>削除</button>
<button id="e;id_submit"e; type="e;submit"e;>送信</button>
</form>
<script>
const uploadObj = document.getElementById("e;id_upload"e;);
const previewObj = document.getElementById("e;id_preview"e;);
const noImageObj = document.getElementById("e;id_no_image"e;);
const imageInputObj = document.getElementById("e;id_input"e;);
const removeObj = document.getElementById("e;id_remove"e;);
const submitObj = document.getElementById("e;id_submit"e;);
// クリック時にはファイル選択
uploadObj.addEventListener("e;click"e;, () => imageInput.click());
// プレビュー表示
imageInputObj.addEventListener("e;change"e;, (e) => {
const file = e.target.files[0];
if (!file) return;
previewObj.removeAttribute("e;hidden"e;);
previewObj.src = URL.createObjectURL(file);
}, false);
//
uploadObj.addEventListener("e;dragover"e;, (e) => {
e.stopPropagation();
e.preventDefault();
uploadObj.style.background = "e;#cccccc"e;;
});
//
uploadObj.addEventListener("e;dragleave"e;, (e) => {
e.stopPropagation();
e.preventDefault();
uploadObj.style.background = "e;#ffffff"e;;
});
// ドロップ
uploadObj.addEventListener("e;drop"e;, (e) => {
e.stopPropagation();
e.preventDefault();
uploadObj.style.background = "e;#ffffff"e;;
const files = e.dataTransfer.files;
if (files.length > 1) return;
imageInputObj.files = files;
previewObj.removeAttribute("e;hidden"e;);
previewObj.src = URL.createObjectURL(imageInputObj.files[0]);
});
// 削除
removeObj.addEventListener("e;click"e;, (e) => {
previewObj.setAttribute("e;hidden"e;, true);
previewObj.src = "e;"e;;
});
</script>
</body>
</html>
サーバレスポンステンプレート: upload.html
<html>
<head>
</head>
<body>
画像アップロード
{{ title }}
</body>
</html>