LoginSignup
64

More than 3 years have passed since last update.

posted at

updated at

Flaskで簡単につくる、画像処理した結果を見るだけのWebサービス

概要

タイトル通り

どういうときに使うの?

とりあえず作った画像処理プログラムをGUIで動かせるようにしたい時とか

どんなものができるの?

画像を送信するとサーバ内で任意の画像処理がされて、処理された画像の一覧が表示されていく。
(サーバ内のimagesディレクトリ内に処理された画像が保存されていく)

a.gif

必要なもの

Flask, OpenCV(画像処理に使う場合)

コード

python server.pyで起動する。

server.py
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
import numpy as np
import cv2
from image_process import canny
from datetime import datetime
import os
import string
import random

SAVE_DIR = "./images"
if not os.path.isdir(SAVE_DIR):
    os.mkdir(SAVE_DIR)

app = Flask(__name__, static_url_path="")

def random_str(n):
    return ''.join([random.choice(string.ascii_letters + string.digits) for i in range(n)])

@app.route('/')
def index():
    return render_template('index.html', images=os.listdir(SAVE_DIR)[::-1])

@app.route('/images/<path:path>')
def send_js(path):
    return send_from_directory(SAVE_DIR, path)

# 参考: https://qiita.com/yuuuu3/items/6e4206fdc8c83747544b
@app.route('/upload', methods=['POST'])
def upload():
    if request.files['image']:
        # 画像として読み込み
        stream = request.files['image'].stream
        img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8)
        img = cv2.imdecode(img_array, 1)

        # 変換
        img = canny(img)

        # 保存
        dt_now = datetime.now().strftime("%Y_%m_%d%_H_%M_%S_") + random_str(5)
        save_path = os.path.join(SAVE_DIR, dt_now + ".png")
        cv2.imwrite(save_path, img)

        print("save", save_path)

        return redirect('/')

if __name__ == '__main__':
    app.debug = True
    app.run(host='0.0.0.0', port=8888)

画像処理のサンプル
想定するユースケースではここに自分の画像処理プログラムを用いる。

image_process.py
import cv2

def canny(image):
    return cv2.Canny(image, 100, 200)

以下ウェブのソース(templatesディレクトリ内に格納する必要があります)

templates/layout.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>API Sample</title>
  </head>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>
templates/index.html
{% extends "layout.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="images/{{ path }}" style="margin-top: 10px; vertical-align: bottom; width: 200px;">
      {{ path }}
    </div>
  {% endfor %}
{% endif %}

{% endblock %}

参考資料

以下の資料を一部参考にさせていただきました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
64