Flask＋Pillowで画像合成アプリを作成する

Flaskを使った画像合成アプリケーションを作成します。Pillowモジュールをインストールしておきます。

#概要

フォームから合成元の画像を選択させ、ロゴなど合成したいファイルを選択。実行結果に合成画像を表示します。今回は以下の2つの画像を合成します。

![limited_car.jpg](https://qiita-image-store.s3.amazonaws.com/0/71585/98173802-f16b-bf30-a66a-42c2a6471242.jpeg)

![momo.png](https://qiita-image-store.s3.amazonaws.com/0/71585/c8ccb065-1272-bd44-a6cb-e6641000ab36.png)

例によってまた桃です。

#コード実態

合成時に名前が上書きされてしまうようになってますが、そのあたりはなんとかしてください。

```imgadd.py
import os
from PIL import Image
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session
from werkzeug import secure_filename
app = Flask(__name__)

UPLOAD_FOLDER = './uploads'
ALLOWED_EXTENSIONS = set(['jpg','png','gif'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = os.urandom(24)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/')
def index():
    return render_template('img.html')


@app.route('/show_img', methods=['GET', 'POST'])
def show_img():
    if request.method == 'POST':
        img_data = request.files['img_data']
        logo_data = request.files['logo_data']

        if img_data and allowed_file(img_data.filename):
            filename = secure_filename(img_data.filename)
            img_data.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            SQUARE_FIT_SIZE = 600
            MAIN_FILENAME = 'uploads/' + filename
            im = Image.open(MAIN_FILENAME)
            im.thumbnail((SQUARE_FIT_SIZE, SQUARE_FIT_SIZE))
            width, height = im.size

        if logo_data and allowed_file(logo_data.filename):
            filename = secure_filename(logo_data.filename)
            logo_data.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            SQUARE_FIT_SIZE = 100
            LOGO_FILENAME = 'uploads/' + filename
            logo_im = Image.open(LOGO_FILENAME)
            logo_width, logo_height = logo_im.size

            im.paste(logo_im, (width-logo_width, height-logo_height), logo_im)
            im.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            img_url = '/uploads/' + filename

            return render_template('img.html', img_url=img_url)


@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    app.debug = True
    app.run()
```

```img.html
{% extends "base.html" %}
{% block content %}
<form method="post" action="{{ url_for('show_img') }}" enctype="multipart/form-data">
  メイン画像を選択<input type="file" id="img_data" name="img_data">
  ロゴを選択<input type="file" id="logo_data" name="logo_data">
  <input type="submit" value="送信">
</fomr>
<div>
  {% if img_url %}
  <p><img src="{{ img_url }}"></p>
  {% endif %}
</div>
{% endblock %}
```

#実行

<img width="320" alt="スクリーンショット 2017-06-06 12.58.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/b7faa4ca-751b-0f19-5cec-2461dc35b0c9.png">

簡素なフォームですが、早速画像を送信してみます。

<img width="637" alt="スクリーンショット 2017-06-06 12.58.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/01a8a3f1-ac33-6499-4f5c-3b10ca5a5403.png">

無事成功。