【问题标题】:Flask to return image stored in database烧瓶返回存储在数据库中的图像
【发布时间】:2012-06-16 13:31:24
【问题描述】:

我的图像存储在 MongoDB 中,我想将它们返回给客户端,代码如下:

@app.route("/images/<int:pid>.jpg")
def getImage(pid):
    # get image binary from MongoDB, which is bson.Binary type
    return image_binary

但是,我似乎无法在 Flask 中直接返回二进制文件?到目前为止我的想法:

  1. 返回二进制图像的base64。问题是 IE
  2. 创建一个临时文件,然后使用send_file 将其返回。

有更好的解决方案吗?

【问题讨论】:

标签: python binary flask


【解决方案1】:

以下内容对我有用(Python 3.7.3):

import io
import base64
# import flask
from PIL import Image

def get_encoded_img(image_path):
    img = Image.open(image_path, mode='r')
    img_byte_arr = io.BytesIO()
    img.save(img_byte_arr, format='PNG')
    my_encoded_img = base64.encodebytes(img_byte_arr.getvalue()).decode('ascii')
    return my_encoded_img

...
# your api code
...
img_path = 'assets/test.png'
img = get_encoded_img(img_path)
# prepare the response: data
response_data = {"key1": value1, "key2": value2, "image": img}
# return flask.jsonify(response_data )

【讨论】:

  • 在服务器端使用此代码,如何在 javascript 中对其进行解码?将字符串编码为ascii,然后将字节解码为base 64并将其保存为图像?
  • 你好,有没有办法更新以反映显示 js 部分?
  • 转换可以以示例图像的形式显示,该示例图像被读取并转换为 base64 格式,然后再恢复为原始格式。 ``` '使用严格';常量 fs = 要求('fs');让 buff = fs.readFileSync('images/inp.png');让 base64data = buff.toString('base64'); console.log(base64data) let buffOut = new Buffer(base64data, 'base64'); fs.writeFileSync('images/out.png', buffOut); console.log('Base64图像数据转成文件:out.png'); ```现在你可以弄清楚你的角色@boardkeystown
【解决方案2】:

假设我有存储的图像路径。下面的代码有助于通过发送图像。

from flask import send_file
@app.route('/get_image')
def get_image():
    filename = 'uploads\\123.jpg'
    return send_file(filename, mimetype='image/jpg')

uploads 是我的 123.jpg 图像所在的文件夹名称。

[PS:上传文件夹应该在你的脚本文件的当前目录中]

希望对你有帮助。

【讨论】:

  • 如果图像在内存中怎么办。
【解决方案3】:

使用数据创建响应对象,然后设置内容类型标头。如果您希望浏览器保存文件而不是显示文件,请将内容处置标头设置为 attachment

@app.route('/images/<int:pid>.jpg')
def get_image(pid):
    image_binary = read_image(pid)
    response = make_response(image_binary)
    response.headers.set('Content-Type', 'image/jpeg')
    response.headers.set(
        'Content-Disposition', 'attachment', filename='%s.jpg' % pid)
    return response

相关:werkzeug.Headersflask.Response

您可以将类似文件的 oject 和标头参数传递给 send_file 以使其设置完整的响应。二进制数据使用io.BytesIO

return send_file(
    io.BytesIO(image_binary),
    mimetype='image/jpeg',
    as_attachment=True,
    attachment_filename='%s.jpg' % pid)

【讨论】:

  • send_file 发送后是否关闭文件对象?如果它不是 BytesIO,而是需要调用 close() 的其他文件对象,谁会调用它?
  • 使用 Python 3 和 Flask 0.12,提供二进制字符串 (b'&lt;binary image data&gt;') 可能会导致 UnicodeErrorsend_file() 可能会更好。
  • @Baruch 使用with 子句?
  • 尽管有关于图像的问题,这里是content-type 任何文件类型application/octet-stream
【解决方案4】:

只是想确认 dav1d 的第二个建议是正确的 - 我对此进行了测试(其中 obj.logo 是一个 mongoengine ImageField),对我来说很好:

import io

from flask import current_app as app
from flask import send_file

from myproject import Obj

@app.route('/logo.png')
def logo():
    """Serves the logo image."""

    obj = Obj.objects.get(title='Logo')

    return send_file(io.BytesIO(obj.logo.read()),
                     attachment_filename='logo.png',
                     mimetype='image/png')

比手动创建响应对象并设置其标头更容易。

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 2020-06-09
    • 2021-12-08
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2012-01-28
    相关资源
    最近更新 更多