はじめに
これまではDjangoを触ってきましたが、Flaskも触ってみようということで今回作成しました。そして今後は物体検出ができるWebアプリを作りたいので、その前段階として画像をアップできる簡易なWebアプリを作成することを決めました。
今回の目標:Falskに慣れるために単に画像をUploadできるアプリを作成する
完成品
実際に作成したところ次のようなものになりました。
実行環境
使用したパッケージ等のバージョンは以下の通りです。
python 3.8.5
flask 1.1.2
作成したアプリについて
ディレクトリ構造
まず、ディレクトリ構造は以下の通りです。
myProject
├── app.py
├── static
│ └── media(画像がここに保存される)
└── templates
├── base.html
└── index.html
コード
次にコードです。
from pathlib import Path
from werkzeug.utils import secure_filename
from flask import Flask
from flask import render_template, redirect, send_from_directory, request
BASE_DIR = Path(__file__).resolve().parent
UPLOAD_FOLDER = BASE_DIR / "static" / "media"
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}
app = Flask(__name__, static_folder="static")
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/', methods=["GET", "POST"])
def index():
# トップページ
return render_template("index.html", images=[p.relative_to(BASE_DIR) for p in list(UPLOAD_FOLDER.glob('*.*'))])
@app.route('/images/<path>')
def send_js(path):
# 画像ページ
return send_from_directory(app.config["UPLOAD_FOLDER"], path)
@app.route('/upload', methods=["POST"])
def upload():
if 'image' not in request.files:
# ファイルが選択されていない場合
print('ファイルが選択されていません')
return redirect('/')
img = request.files['image']
# 画像として読み込み
if img.filename == "":
# ファイル名がついていない場合
print("ファイル名がありません")
return redirect('/')
if img and allowed_file(img.filename):
filename = secure_filename(img.filename)
try:
img.save(UPLOAD_FOLDER / filename)
# 画像を保存
except Exception as e:
print(f"画像の保存に失敗: {e}")
return redirect('/')
if __name__ == '__main__':
app.run()
templateファイルは以下の通りです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>画像処理</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends "base.html" %}
{% block content %}
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" accept="image/png, image/jpeg">
<button type="submit">submit</button>
</form>
{% if images %}
{% for path in images %}
<div>
<img src="../{{ path }}" style="margin-top: 10px; vertical-align: bottom; width: 128px;"
alt="image">
<br>
<p>{{ path }}</p>
</div>
{% endfor %}
{% endif %}
{% endblock %}
index.htmlは後に拡張しやすい様にbaseをベースにして作成しました。
ハマったところ
画像pathの取り出し方
絶対パスや相対パスは頭で考えてもわからないのでpathを色々試して解決しました。
static_floderの設定
はじめはapp.pyにおいてstatic_folderを宣言していませんでしたが、宣言をしたことによって画像が表示される様になりました。
x: app = Flask(name)
◯: app = Flask(name, static_folder="static")
参考文献
参考にした文献は次の通りです。
以上でこの記事は終わりです。ここまでお読みいただきありがとうございました。