我正在模板中渲染一个实例列表,每个实例都有一个二进制blob图像。要渲染图像,我需要使用base64对它们进行编码。我不确定如何在循环中编码每个图像,下面的代码不起作用。我也不确定是否将对象列表和编码图像列表传递给render_template
会增加网络流量。如何正确编码图像列表,这是否有效?
class A:
number = ndb.IntegerProperty()
image = ndb.BlobProperty()
@app.route('/show-all')
def show_all():
all = A.query().order(A.number).fetch()
encoded_images = [b64encode(image) for all.image in all] # Doesn't work
return make_response(render_template("template.html", title="A", objects=all, images=encoded_images))
答案 0 :(得分:1)
通过向render_template
发送多个内容,您不会发送任何“额外数据”,通过网络发送的唯一数据是最终呈现的模板。
构建所有编码图像的列表略微效率低,因为它们将一次存在于内存中。相反,您可以向模型添加属性,以便在渲染时可以在每个实例上使用a.b64_image
。
class A:
image = ndb.BlobProperty()
@property
def b64_image(self):
return b64encode(self.image)
然后在模板中,您可以遍历对象列表中的每个项目,并获取每个项目的base64编码图像。
return render_template('objects.html', objects=objects)
{% for item in objects %}
<div>
<img src="data:;base64,{{ item.b64_image }}"/>
</div>
{% endfor %}
附注:您不必致电make_response
,Flask会自动将字符串(从render_template
返回)转换为回复。此外,make_response
和render_template
是Flask的一部分,而不是Flask-Restful。
正如我在my answer to your previous question中所说的那样,将图像作为数据发送是无效的,因为它们被嵌入到每次生成和发送的html中,而不是由客户端缓存的单独文件。更有效的解决方案是单独存储和提供文件,并将文件的路径存储在数据库中。
答案 1 :(得分:0)
从第二个问题开始: 我不确定你的实现,但是你的响应可能只包含某种类型的web页面,因此不会通过Internet发送任何python对象,那么为什么你认为调用具有不同参数的python函数会导致你要向最终用户发送额外的字节吗?
然而,毕竟,你可以立刻解决这两个问题。只需将一个类对象传递给make_response函数,然后里面这个函数(因此问题2解决了)你可以做(实际上你的伪代码非常接近):
encoded_images = [b64encode(obj.image) for obj in objects]