我正在尝试制作一个接受文本输入、生成图像,然后在 html 中显示该图像的网站。
当我有本地测试实现时,通过将图像写入静态目录可以正常工作,但是当我推送到谷歌云时,我不允许写入目录。我想出了如何将图像保存到我的 google 云存储桶中,但现在我无法将图像恢复显示在 html 模板中。
我使用 Flask 和 python 3.7
这是我正在做的:
from flask import Flask, render_template, request, send_file
import time
#import cloudstorage
import io, os
from google.cloud import storage
import tempfile
import functions
app = Flask(__name__)
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
@app.route("/")
def home():
return render_template("home_css.html")
@app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']
URL = functions.main(text)
print(URL)
return render_template("return_img_css.html", picture_path = URL, screen_name = text)
其中函数部分包含一个块,该块可以成功保存图像以返回图像的网址:
def make_plot():
....
# NEED to SAVE THE IMAGE TO GOOGLE CLOUD
client = storage.Client(project='meytweets')
bucket = client.bucket('meytweets.appspot.com')
savename = 'static/'+ screen_name+ '_network.png'
blob = bucket.blob(savename)
# temporarily save image to buffer
buf = io.BytesIO()
plt.savefig(buf, format='png')
# upload buffer contents to gcs
blob.upload_from_string(
buf.getvalue(),
content_type='image/png')
buf.close()
return blob.public_url
该网址通常如下所示: https://storage.googleapis.com/meytweets.appspot.com/static/twitter_network.png
HTML 模板如下所示:
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %} Network for Twitter User: {{ screen_name }} {% endblock %}</h1>
<img src="{{ picture_path }}" >
{% endblock %}
这是 app.yaml:
runtime: python37
env_variables:
CLOUD_STORAGE_BUCKET: meytweets.appspot.com
handlers:
- url: /static
static_dir: public
- url: /.*
script: auto
正如我上面写的,它确实将图像保存到我的谷歌云存储桶中,但随后我无法将其恢复以显示在 html 中: screenshot
我对其他不写入谷歌云的策略持开放态度,任何可以显示我在 matplotlib 中生成的图像的方法都适合我。
答案 0 :(得分:1)
当您在无服务器环境中运行您的应用时,只有 /tmp
目录是可写的。您不能更改其他目录的内容,例如 /static
。此外,/tmp
目录是内存文件系统,因此,当实例被杀死时,所有 /tmp
都会消失。
现在,您可以尝试在处理程序中设置 /tmp
。我从未测试过,不确定结果及其一致性。
另一种解决方案是将图像保存到 Google Cloud Storage,最后使用 Google Cloud Storage 中的图像生成 HTML,publicly accessible of course。