ドラッグ&ドロップでアップロードする画像を指定し、画像をサーバに送信します。
サーバは 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>