やりたいこと
flaskを使った画像処理のwebアプリを作っています。
画像をアップロードされたらその画像をpython側のグローバル変数imgs(辞書)に自動生成したuniqueIDをキーとして格納しておき、その後、webページの更新があっても画像を参照できる状態にしたいです。
何度も参照したい理由は、
すでに用意されている背景画像に、アップロード画像をペーストしたあとで
位置調整や二値化パラメータなどの微調整をしていくために
何度かページを更新する必要があると考えたためです。
ユーザーによる操作の流れ
画像をアップロード
↓
二値化や位置調整のパラメータをスライダーで決定
↓
変換ボタンをクリック(この後にpython側でimgsを参照しています)
↓
画像処理とユーザーによる微調整がされた画像が表示される
プログラムの流れ
webページで画像をアップロード
↓
javascriptでuniqueIDを生成
↓
python側のimgs(辞書)にkeyをuniqueID、valueをアップロードされた画像として格納
↓
webページの変換ボタンをクリック
↓
webページからGETでURLに画像処理のパラメータとuniqueIDのパラメータを載せて送信
↓
python側でimgs[uniqueID]で画像を参照し(←ここの参照ができるときとできないときがあります)
URLから得られたパラメータに従って画像処理を施して、webページに表示
問題
実際にデプロイして、画像アップロード後にimgsにuniqueIDで参照して画像処理を行い、webページに表示する形を取っているのですが、imgsにその「キーは存在しません」となります。
しかし、変換ボタンを何度かクリックして、「キーが存在しません」が数回出たあとでも、
何度も参照をしていると参照できる時があり、
なぜ参照できるときとできない時があるのかがわかりません。
試したこと
画像のアップロードに時間がかかっているのかと考え、アップロード後に数分待ってから参照を試みましたが、できるときとできないときがあり、よくわかりませんでした。
知りたいこと
herokuにおいてpythonのグローバル変数はどんな状態になっているのでしょうか。
グローバル変数の中身を参照できるときがあるので、変数は保持されているのだと思いますが、なぜ参照できないという状態があるのでしょうか。
プログラムのバグというよりは、herokuのシステムの特徴だと感じました。
よろしくお願いいたします。
該当するプログラム
python
1app = Flask(__name__, static_url_path="") 2 3# 該当のグローバル変数 4imgs = {} 5 6 7@app.route('/upload', methods=['POST', 'GET']) 8def upload(): 9 # グローバル変数imgsを使用する 10 global imgs 11 # webページ側で生成されたuniqueIDをURLから取得 12 if request.method == 'POST': 13 image_id = request.form.get( 14 'imageUniqueID', 'サンプル画像ID', type=str) 15 else: 16 image_id = request.args.get( 17 'imageUniqueID', 'サンプル画像ID', type=str) 18 try: 19 if request.files['image']: 20 # POSTで受け取った画像をPILの画像に変換 21 stream = request.files['image'].stream 22 img_array = np.asarray(bytearray(stream.read()), dtype=np.uint8) 23 img = cv2.imdecode(img_array, cv2.IMREAD_UNCHANGED) 24 img = Image.fromarray(img) 25 26 # グローバル変数imgsにuniqueIDをキーとして画像を格納 27 imgs[image_id] = img 28 except: 29 pass 30 31 # グローバル変数imgsに格納された画像を参照する 32 try: 33 img = imgs[image_id] # ←ここで参照できるときとできないときがあります。 34 except: 35 # キーが存在しないなどのエラーが出たらサンプル画像を取得する(エラー画面を出さないため) 36 img = Image.open('サンプル画像パス') 37 38 # 画像処理を施したアップロード画像を用意された背景画像にペーストする 39 dst = webページに表示する画像 40 dst = dstをwebページ表示用データに変換 41 42 return render_template('index.html', dst=dst) 43 44 45if __name__ == '__main__': 46 app.debug = True 47 app.run(host='0.0.0.0', port=int(os.environ.get("PORT", 5000)))
回答1件
あなたの回答
tips
プレビュー