html - 如何在 HTML 中显示 ImageGridFSProxy?

标签 html mongodb flask pymongo gridfs

我在 MongoDB 中存储了几个图像,我现在想在网页中显示它们。我在我的应用程序中使用 Flask。该记录有一个名为“payload”的二进制字段

class BinaryFile(mongo.Document):
    created_at = mongo.DateTimeField(default=datetime.datetime.now, required=True)
    file_name = mongo.StringField(max_length=255, required=True)
    payload = mongo.ImageField(required=False)

我想显示有效负载。有关如何执行此操作的任何线索?我试过了

<img src="{{ image.payload }}"/>

这只是给了我一个损坏的链接。然后页面的源代码为

<img src="&lt;ImageGridFsProxy: None&gt;"/>

如果我尝试

<img src="{{ image.payload.read() }}"/>

我明白了

UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)

有点难住了。有任何想法吗?谢谢!

最佳答案

image.payload.read() 返回图像的原始数据,这就是我们想要的,只是我们不想将其放在 IMG 标签的 src 属性中。

我们想要的是将原始图像数据作为图像提供,并将该图像的 URL 放入 src 属性。

Here is one example how it can be done with a temporary file. 这很可能就是您想要的解决方案。

from tempfile import NamedTemporaryFile
from shutil import copyfileobj

tempFileObj = NamedTemporaryFile(mode='w+b',suffix='jpg')
copyfileobj(image.payload,tempFileObj)
tempFileObj.seek(0,0)

然后在 View 中提供文件

from flask import send_file

@app.route('/path')
def view_method():
    response = send_file(tempFileObj, as_attachment=False, attachment_filename='myfile.jpg')
    return response

也许可以直接从 ImageGridFSProxy 对象发送图像数据并跳过临时文件,但我不确定。

----------

既然你已经完成了代码,我将发布我本来会做的方式。以及我试图解释的方式。 :)

这是我的 app.py。

from flask import Flask, send_file, render_template
import mongoengine as mo

app = Flask(__name__)
c = mo.connection.connect('localhost')

@app.route('/')
def index():
    images = MyDoc.objects.all()
    return render_template('template.html', images=images)

# Separate view for the images
@app.route('/image/<img_name>')
def image(img_name):
    image = MyDoc.objects(file_name=img_name).first()
    # This is where the tempfile stuff would have been if it would
    # have been needed.
    if image:
        return send_file(image.payload, mimetype='image')
    else:
        return "404" # might want to return something real here too

class MyDoc(mo.Document):
    file_name = mo.StringField(max_length=255, required=True)
    payload = mo.ImageField(required=True)

if __name__ == "__main__":
    app.run(debug=True)

这是模板。

<html>
<body>
<div>
    This is a body!
    <div>
        {% if images %}
           {% for image in images %}
             {{ image.file_name }}
             <img src="/image/{{ image.file_name }}" />
             I'm an image!<br><br>
           {% endfor %}
        {% endif %}

    </div>
</div>
</body>
</html>

整个 tempfile 的事情是不必要的,因为有效负载可以直接使用 send_file 发送。需要 mimetype 来告诉浏览器“这是一个图像”,并且浏览器应该只显示它​​而不下载它。这不是我之前怀疑的 as_attachment

这样就不需要使用tempfile保存文件或将它们保存到静态提供服务的目录中。

关于html - 如何在 HTML 中显示 ImageGridFSProxy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28260499/

相关文章:

javascript - 如何在前端显示mongodb的内容?

python - 如何让 gunicorn 记录未捕获的异常?

html - div的过滤器适当性如何不会影响div内部的文本?

javascript - 无同源连接策略下的WebSocket安全性

css - Angular-material:限制 md-content 高度

python - 在 Tomcat 上使用 Jython 部署 Flask 应用程序的最佳方式是什么?

python - Celery:防止在排队的任务过多时添加更多任务

javascript - html按钮执行jquery和javascript?

javascript - 空 XmlHttpRequest.response 但 XHR 包含我的数据

javascript - 无法使用 nodeJS 连接到我的 mongoDB docker