Вопрос по flask, binary, python – Колба для возврата изображения, хранящегося в базе данных

50

Мои изображения хранятся в MongoDB, и я хотел бы вернуть их клиенту, вот как выглядит код:

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

Однако кажется, что я не могу вернуть двоичный файл непосредственно во Flask? Моя идея до сих пор:

Return the base64 of the image binary. The problem is that IE<8 doesn't support this. Create a temporary file then return it with send_file.

Есть ли лучшие решения?

возможный дубликатHow to return images in flask response? erickrf

Ваш Ответ

3   ответа
87

Создайте объект ответа с данными, а затем установите заголовок типа содержимого. Установите заголовок размещения контента на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.Headers а такжеflask.Response

Вы можете передать подобный файлу объект и аргументы заголовкаsend_file чтобы он создал полный ответ. использованиеio.BytesIO для двоичных данных:

return send_file(
    io.BytesIO(image_binary),
    mimetype='image/jpeg',
    as_attachment=True,
    attachment_filename='%s.jpg' % pid)
Использование Python 3 и Flask 0.12 с двоичной строкой (b'<binary image data>') может привести кUnicodeError. send_file() может быть просто лучше
@Baruch использоватьwith статья?
Send_file закрывает объект файла после отправки? Если это не BytesIO, а какой-то другой файл-объект, который требует вызова close (), кто будет его вызывать?
37

Просто хотел подтвердить, что второе предложение 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')

Проще, чем вручную создавать объект Response и настраивать его заголовки.

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: папка для загрузки должна находиться в текущем каталоге, начиная с вашего файла скрипта]

Надеюсь, поможет.

Что делать, если изображение в памяти.

Похожие вопросы