🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2419閲覧

定期的に変化する画像をFlaskで読み込みたい

BuhKeil

総合スコア34

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/03/31 07:04

やりたいこと

  1. Componentクラスで日付の文字列を付した1200*960サイズの画像を作成。
  2. 画像ファイル名("test.jpg/?=37635648525"のような感じ)を格納する変数を宣言(=IMAGE_NAME)。
  3. IMAGE_NAMEを組み込んだindex.htmlを作成し、localhost:5000でアクセスした時にindex.htmlを描画。
  4. 5秒毎に、test.jpgを作成し直し、IMAGE_NAMEに格納。

今回のケースでは、日付が書かれた画像を5秒毎にリフレッシュすることをしたいのですが、実現できていません。下記にコードやエラーについて書きました。おわかりの方、アドバイスをお願いします。

環境

  • Windows10 64bit
  • Python v3.8.3
  • flaskライブラリ(v1.1.2)
  • PILLOWライブラリ(v8.1.1)

コード

python3

1from flask import Flask, render_template 2from PIL import Image, ImageFont, ImageDraw 3import random 4import datetime 5import time 6import os 7 8IMAGE_NAME = "" 9 10class Component(): 11 12 DefaultFontName = "KikaiChokokuJIS-Md.otf" 13 DefaultFontSize = 40 14 font= ImageFont.truetype(DefaultFontName, DefaultFontSize) 15 16 def __init__(self, mode="RGB", size=(1200,960),bkcolor=(20,0,0)): 17 global font 18 self.mode = mode 19 self.size = size 20 self.bkcolor = bkcolor 21 22 self.image = Image.new(self.mode,self.size,self.bkcolor) 23 self.draw = ImageDraw.Draw(self.image) 24 25 def Output(self): 26 self.draw.text((300,500),str(datetime.datetime.now()),fill=(88,126,255),font=Component.font) 27 self.image.save("static/images/test.jpg", quality=85) 28 code = str(random.random() * 1000) 29 30 return "test.jpg/?=" + code 31 32 33app = Flask(__name__) 34 35@app.route("/") 36def index(): 37 38 # defの外の変数を呼び出したいのでglobalで呼び出す 39 global IMAGE_NAME 40 41 html_string = """ 42 <!DOCTYPE html> 43 <html lang='ja'> 44 <head> 45 <meta charset='utf-8'> 46 <meta http-equiv='Cache-Control' content='no-cache'> 47 <meta http-equiv='Pragma' content='no-cache'> 48 <meta http-equiv='Refresh' content='5'> 49 <title>texst</title> 50 </head> 51 <body> 52 <p> 53 <img width=1200 src='static/images/""" + IMAGE_NAME + """'/> 54 </p> 55 </body> 56 </html> 57 """ 58 59 f = open("templates/index.html", mode="wt", encoding="utf-8") 60 f.write(html_string) 61 f.close() 62 63 return render_template("index.html") 64 65 66if __name__ == "__main__": 67 app.run(debug=True) 68 69 while True: 70 # 前回作成したtest.jpgを削除 71 os.remove("static/images/test.jpg") 72 73 # 初期化して画像を再作成する 74 test_image = Component() 75 IMAGE_NAME = test_image.Output() 76 77 # 5秒待つ 78 time.sleep(5)

エラー

  • エラーになる原因の1つめは画像が作成されていないため

クラスのdef Output(self)の中で、self.image.save("static/images/test.jpg")と書いているのですが、
static/images フォルダに"test.jpg"画像ファイルが作成されません。

CMDから実行しChromeでlocalhost:5000でアクセスすると、
127.0.0.1 -- [日付] "'[37mGET / HTTP/1.1'[0m" 200 -
127.0.0.1 -- [日付] "'[37mGET /static/images/ HTTP/1.1'[0m" 404 -
がひたすら繰り返し出てきます。画像が作成されていないのが原因で404エラーになっています。

  • エラーになる原因の2つめは、IMAGE_NAMEにファイル名文字列が渡っていないため

出力されたhtmlファイルのソースを見ると、
<src width=1200 src="static/images/'/>
となっていて、期待する、
<img width=1200 src='static/images/test.jpg/?=134253564'>
となっていません。IMAGE_NAMEの変数の使い方が間違っているのでしょうか?

自分では、ここまでエラーを切り分けるところまでできたつもりですが、どう対処すれば良いのか解りません。

アドバイスよろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

恐らく、最後の方のapp.runでwebサーバが起動した状態で待機していて、そのあとのwhileループまで処理が進んでないのではないかと思います。

どうしても同じプログラムの中でサーバの起動と5秒ごとの画像ファイル作成をしたいなら、スレッドなどを使ってで並列処理する必要がありそうに見えます(実装方法はいろいろ注意点がありそうで、またこの質問の本題から外れるので、説明は省略します)。

5秒ごとの画像ファイル作成をどうしてもしたいなら、別プログラム(別プロセス)で実行すれば比較的楽かと思います。

5秒ごとのファイル作成にこだわらないなら、リクエストを処理するタイミング(質問にあるコードではindex関数の中)でファイル作成処理を呼び出すのが比較的楽かと思います。

投稿2021/04/04 03:08

msiz07

総合スコア172

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BuhKeil

2021/04/07 03:43

msiz07さま、返事が遅くなり、すみません。 プログラムを分ける方法で対処してみます。 アドバイスありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問