Как отправить изображение, сгенерированное PIL, в браузер? - PullRequest
45 голосов
/ 24 октября 2011

Я использую колбу для своего приложения. Я хотел бы отправить изображение (динамически генерируемое PIL) клиенту без сохранения на диске.

Есть идеи, как это сделать?

Ответы [ 5 ]

146 голосов
/ 16 апреля 2012

Вот версия без каких-либо временных файлов и т.п. (см. здесь ):

def serve_pil_image(pil_img):
    img_io = StringIO()
    pil_img.save(img_io, 'JPEG', quality=70)
    img_io.seek(0)
    return send_file(img_io, mimetype='image/jpeg')

Чтобы использовать в своем коде, просто выполните

@app.route('some/route/')
def serve_img():
    img = Image.new('RGB', ...)
    return serve_pil_image(img)
20 голосов
/ 25 октября 2011

Во-первых, вы можете сохранить изображение в временный файл и удалить локальный файл (если он у вас есть):

from tempfile import NamedTemporaryFile
from shutil import copyfileobj
from os import remove

tempFileObj = NamedTemporaryFile(mode='w+b',suffix='jpg')
pilImage = open('/tmp/myfile.jpg','rb')
copyfileobj(pilImage,tempFileObj)
pilImage.close()
remove('/tmp/myfile.jpg')
tempFileObj.seek(0,0)

Во-вторых, установить временный файл для ответа (согласно этот вопрос о стекопереработке ):

from flask import send_file

@app.route('/path')
def view_method():
    response = send_file(tempFileObj, as_attachment=True, attachment_filename='myfile.jpg')
    return response
7 голосов
/ 08 декабря 2011

Оказывается, что колба дает решение (rtm для меня!):

from flask import abort, send_file
try:
    return send_file(image_file)
except:
    abort(404)
7 голосов
/ 16 ноября 2011

Я тоже боролся в той же ситуации. Наконец, я нашел его решение, используя приложение WSGI, которое является допустимым объектом для "make_response" в качестве аргумента.

from Flask import make_response

@app.route('/some/url/to/photo')
def local_photo():
    print('executing local_photo...')
    with open('test.jpg', 'rb') as image_file:
        def wsgi_app(environ, start_response):
            start_response('200 OK', [('Content-type', 'image/jpeg')])
            return image_file.read()
        return make_response(wsgi_app)

Пожалуйста, замените операции открытия изображения соответствующими операциями PIL.

6 голосов
/ 23 августа 2018

г. Мистер действительно проделал отличную работу. Мне пришлось использовать BytesIO () вместо StringIO ().

def serve_pil_image(pil_img):
    img_io = BytesIO()
    pil_img.save(img_io, 'JPEG', quality=70)
    img_io.seek(0)
    return send_file(img_io, mimetype='image/jpeg')
...