如何在 HTML 中显示 ImageGridFSProxy?
How to display ImageGridFSProxy in HTML?
我在 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)
我想展示payload。有关如何执行此操作的任何线索?我试过了
<img src="{{ image.payload }}"/>
这简直让我崩溃了link。该页面的来源显示为
<img src="<ImageGridFsProxy: None>"/>
如果我尝试
<img src="{{ image.payload.read() }}"/>
我明白了
UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
有点难过。有任何想法吗?谢谢!
image.payload.read()
returns 图片的原始数据,这就是我们想要的,除了我们不想把它放在 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)
然后在视图中提供文件
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 对象发送图像数据并跳过临时文件,但我不确定。
------------
既然你已经完成了代码,我将post按照我本来的方式来完成。以及我试图解释的方式。 :)
这是我的 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 来告诉浏览器 "this is an image" 并且浏览器应该只显示它而不是下载它。这不是我之前怀疑的 as_attachment
。
这样就不需要使用 tempfile
保存文件或将文件保存到静态提供的目录中。
非常感谢@sevanteri 让我入门。为了后代,这就是我最终所做的
观点:
@app.route('/index')
def index():
images = BinaryFile.objects.all()
for image in images:
# This was the temp file idea, abandoned...
# tmpImageFile = NamedTemporaryFile(mode="w+b", suffix="jpg", delete=False, dir="app/static/temporary_files")
# copyfileobj(image.payload,tmpImageFile)
# tmpImageFile.seek(0,0)
with open(app.config['TEMPORARY_FILE_DIR'] + "/" + image.file_name, 'wb') as f:
f.write(image.payload.read())
# image.temporary_file_location = app.config['TEMPORARY_FILE_DIR'] + "/" + image.file_name
image.temporary_file_location = "static/tmp/" + image.file_name
return render_template('dashboard.html', images=images)
html:
{% block content %}
<div>
This is a body!
<div>
{% if images %}
{% for image in images %}
{{ image.file_name }}
<img src="{{ image.temporary_file_location }}"/>
I'm an image!<br><br>
{% endfor %}
{% endif %}
</div>
</div>
{% endblock %}
模特:
import datetime
from app import mongo
from flask import url_for
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)
def get_absolute_url(self):
return url_for('post', kwargs={"binary_file": self.file_name})
def __unicode__(self):
return self.title
所以这有点糟糕,因为我正在使用复制命令。它满足了我在 mongo 中保存图像然后显示它们的 POC,我会让我的工程师弄清楚实际文件的管理。他们比我聪明
非常感谢!
我在 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)
我想展示payload。有关如何执行此操作的任何线索?我试过了
<img src="{{ image.payload }}"/>
这简直让我崩溃了link。该页面的来源显示为
<img src="<ImageGridFsProxy: None>"/>
如果我尝试
<img src="{{ image.payload.read() }}"/>
我明白了
UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal not in range(128)
有点难过。有任何想法吗?谢谢!
image.payload.read()
returns 图片的原始数据,这就是我们想要的,除了我们不想把它放在 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)
然后在视图中提供文件
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 对象发送图像数据并跳过临时文件,但我不确定。
------------
既然你已经完成了代码,我将post按照我本来的方式来完成。以及我试图解释的方式。 :)
这是我的 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 来告诉浏览器 "this is an image" 并且浏览器应该只显示它而不是下载它。这不是我之前怀疑的 as_attachment
。
这样就不需要使用 tempfile
保存文件或将文件保存到静态提供的目录中。
非常感谢@sevanteri 让我入门。为了后代,这就是我最终所做的
观点:
@app.route('/index')
def index():
images = BinaryFile.objects.all()
for image in images:
# This was the temp file idea, abandoned...
# tmpImageFile = NamedTemporaryFile(mode="w+b", suffix="jpg", delete=False, dir="app/static/temporary_files")
# copyfileobj(image.payload,tmpImageFile)
# tmpImageFile.seek(0,0)
with open(app.config['TEMPORARY_FILE_DIR'] + "/" + image.file_name, 'wb') as f:
f.write(image.payload.read())
# image.temporary_file_location = app.config['TEMPORARY_FILE_DIR'] + "/" + image.file_name
image.temporary_file_location = "static/tmp/" + image.file_name
return render_template('dashboard.html', images=images)
html:
{% block content %}
<div>
This is a body!
<div>
{% if images %}
{% for image in images %}
{{ image.file_name }}
<img src="{{ image.temporary_file_location }}"/>
I'm an image!<br><br>
{% endfor %}
{% endif %}
</div>
</div>
{% endblock %}
模特:
import datetime
from app import mongo
from flask import url_for
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)
def get_absolute_url(self):
return url_for('post', kwargs={"binary_file": self.file_name})
def __unicode__(self):
return self.title
所以这有点糟糕,因为我正在使用复制命令。它满足了我在 mongo 中保存图像然后显示它们的 POC,我会让我的工程师弄清楚实际文件的管理。他们比我聪明
非常感谢!