6
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

素人でも短時間で作れるWebアプリ入門[画像内英文を和訳するWebアプリ]

Last updated at Posted at 2019-07-21

はじめに

以前作成したpythonスクリプトをWebアプリにして公開してみました。
URL:~~http://ysuzuki.pythonanywhere.com/~~←現在停止中

プログラム自体は気軽に作れるのですが、それをWebアプリにするのは少しハードルが高かったです。同じような人が多くいると思い、公開するまでの過程を記しました。
「こんなPythonスクリプト作ったよ!Webアプリにしたい!」という方は、よかったら参考にしてみてください。

Webアプリにするプログラム

画像内の英文を和訳するPythonスクリプトを作りました
に掲載したプログラムをWebアプリにする。

使用したもの

  • macbook pro
  • python3 (cv2, PIL, pyocr, googletrans)
  • flask
  • pythonanywhere

Flaskをはじめる

~$ pip3 install Flask
~$ mkdir flask-ws
~$ cd flask-ws

こちらに最小規模のソースコードが載っている。以下、引用。

~/flask-ws/simple.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello World!"

if __name__ == '__main__':
    app.run()

このプログラムを実行すると、

run_simple.py
~/flask-ws $ python3 simple.py 
 * Serving Flask app "simple" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

と、ローカルサーバが完成する。最下行にURL(http://127.0.0.1:5000/)が記載されており、ここにアクセスすることでWebアプリにアクセス(?)することができる。ターミナルはこのままにして、好みのブラウザのURL入力欄にhttp://127.0.0.1:5000/と入力すると、

スクリーンショット 2019-07-22 2.07.22.png

アクセスできた。この時、先ほどのターミナルを見てみると、

acces_simple.py
~/flask-ws $ python3 simple.py 
 * Serving Flask app "simple" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [22/Jul/2019 02:07:00] "GET / HTTP/1.1" 200 -

と一番下にGETが追加された。
ここまでで、Flaskそのものの動作確認ができた。

自分のプログラムをFlaskアプリにする

画像取得はこちらが非常に勉強になった。この方のソースコードに上乗せする形で作成することになった。

主な変更部分

  • 変換部分を削除
  • image_process.pyは使わずにapp.pyに直書き
  • 保存したプログラムをpyocrのtoolから開く
  • 読み取った後はファイルを削除する
  • return でリダイレクトではなくてプレーンテキストを返す(ダサいけど)
  • template/index.html<h1>title</h1>, <h3>message</h3>で文字を追加(ダサいけど)

完成したpythonスクリプトは以下。

app.py
# coding: utf-8
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
from PIL import Image
import pyocr
import pyocr.builders
from googletrans import Translator

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():
	title = "画像内の英文を和訳するページです"
    message = "英文の入った画像をアップロードしてください"
    return render_template('index.html', title=title, message=message)

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

@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)

        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)

        tools = pyocr.get_available_tools()
        if len(tools) == 0:
            sys.exit(1)
        tool = tools[0]

        langs = tool.get_available_languages()
        lang = langs[0]

        txt = tool.image_to_string(
            Image.open(save_path),
            lang=lang,
            builder=pyocr.builders.TextBuilder()
        )
        translator = Translator()
        translated = translator.translate(txt, src='en', dest='ja')

        os.system('rm ' + save_path.replace(' ', '\ '))

        return '<h1>和訳ができました!</h1><h2>英文</h2>' + txt + '<h2>和訳</h2>' + translated.text

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

完成したindex.htmlは以下。

template/index.html
{% extends "layout.html" %}
{% block content %}

<h1>画像内の英文を和訳するページです</h1>
<h3>英文の入った画像をアップロードしてください</h3>
<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 %}

以上の結果、画像を受け取って、画像内の英文を抽出して和訳するWebアプリが完成した。完成したWebアプリについては下の方で紹介する。
ここまでは先ほどのhttp://127.0.0.1:5000/のローカルサーバで確認しながら作業を進めた。

pythonanywhereに自分のWebアプリを移す

これまでの作業のプログラムをGithubリモートリポジトリにプッシュしておいた。ここでの作業は基本的にこちらのページを参考にした。なので、ここでは概要だけを記載する。実際に作業する方はリンク先を参考にしてほしい。

  • pythonanywhereに登録→こちら
  • bashコンソールを開く
  • 'git clone https://github.com//`でクローン
  • bash上で動作確認(しなくてよい)
    • pip installpip install userにしないとエラーが発生する
  • dush board上でWeb apps内のの「Open Web Tab」をクリック
  • 「Code」という見出しの/var/www/<user name>_pythonanywhere_com_wsgi.pyを調整
    • project_home変数を自分のプロジェクトホームに変更
    • from app ...行の先頭のappのみを自分のプログラム名に変更
  • Web appページの上の方の「Reload .pythonanywhere.com」をクリック

ブラウザからhttp://<user name>.pythonanywhere.comへアクセスすると、自分で作成したWebアプリを使用することができた。

完成したWebアプリ

ここまで来て、ついに自分のWebアプリが完成した。是非試してみてほしい。
URL:http://ysuzuki.pythonanywhere.com/

上記URLへアクセスすると、

スクリーンショット 2019-07-22 3.44.53.png アップロードを促すページが表示された。 今回は、Wikipediaのホームのスクリーンショットである以下を和訳してみようと思う。 スクリーンショット 2019-07-22 3.45.29.png 「ファイルを選択」をクリックして上の画像を選択すると、 スクリーンショット 2019-07-22 3.50.57.png 「submit」をクリックして少し待つと、 スクリーンショット 2019-07-22 3.47.06.png おお!英文と和訳が出力された!

困ったエラーの解消について

ひとつ困ったエラーがあり、応急処置した。これはどこにも載っておらず自分で考えたので邪道ではあるだろうが、一応記す。
「Reload .pythonanywhere.com」をクリックしてURLにアクセスしても
スクリーンショット 2019-07-22 3.58.27.png
と出てきて、自分のWebアプリが表示されなかった。そこで、<user name>.pythonanywhere.com.error.logを開いたところ、

pythonanywhere_error_log
ModuleNotFoundError: No module named 'pyocr'
ModuleNotFoundError: No module named 'googletrans'

と、pythonでおなじみのエラーが吐かれていた。(実際のlogには他の出力もあったがエラー部分はこれ)
そこで、bash consoleでWebアプリを起動してみても、問題なく動作する。bash上でインストールしたpyocr,googletransたちはbashのユーザ(--user)にインストールされており、そのままでは使えないようだ・・・
そこで考えた応急処置が、

「実行ディレクトリにmoduleを持ってくる」

だ。その流れは以下。

error_handling
$ find / -name pyocr
/home/<user name>/.local/lib/python3.7/site-packages/pyocr
$ cp -r path/to/pyocr path/to/project_directory
$ find / -name googletrans
/home/<user name>/.local/lib/python3.7/site-packages/googletrans
$ cp -r path/to/googletrans path/to/project_directory

この結果、なんとかWebアプリは動いたのだが、カレントディレクトリにライブラリが直接おいてあるというなんとも不恰好な環境になってしまった。本来は仮想環境でやるようである。

おわりに

Webアプリについての知識が少なかったので、多くの人のページを参考にさせていただきました。
取り敢えず動くものをと開発したため、多くの粗があると思いますので、まるまる真似すると危険かもしれません!!
特に、無理矢理解決したpyocr,googletransのimportについてはなんとか改善したいと考えています。(仮想環境でできるのかな?)

参考

6
18
0

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
  3. You can use dark theme
What you can do with signing up
6
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?