如何将PIL生成的图像发送到浏览器?

48 python streaming temporary-files python-imaging-library flask

我正在使用烧瓶进行申请.我想将一个图像(由PIL动态生成)发送到客户端而不保存在磁盘上.

知道怎么做吗?

Mr.*_*Mr. 155

这是一个没有任何临时文件的版本(见这里):

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')
Run Code Online (Sandbox Code Playgroud)

要在代码中使用,请执行

@app.route('some/route/')
def serve_img():
    img = Image.new('RGB', ...)
    return serve_pil_image(img)
Run Code Online (Sandbox Code Playgroud)

  • 对于公认的回复,这是一个非常优越的答案. (10认同)
  • Python3需要使用ByteIO:http://fadeit.dk/blog/post/python3-flask-pil-in-memory-image (6认同)
  • 如何将其插入到我返回的模板中? (5认同)
  • 我现在如何在“img”标签的“src”属性中引用该文件 (2认同)
  • 对于那些询问如何在“img”标签的“src”属性中引用文件的人,只需使用一个端点来提供图像“@app.route('/docs/<filename>')”,然后在HTML 使用 `src="/docs/some_img.jpg" (2认同)

Ada*_*ris 20

首先,您可以将图像保存到临时文件并删除本地文件(如果有的话):

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)
Run Code Online (Sandbox Code Playgroud)

其次,将临时文件设置为响应(根据此stackoverflow问题):

from flask import send_file

@app.route('/path')
def view_method():
    response = send_file(tempFileObj, as_attachment=True, attachment_filename='myfile.jpg')
    return response
Run Code Online (Sandbox Code Playgroud)

  • 临时文件也写入磁盘?这是如何被接受的回应? (2认同)

Dan*_*rez 10

先生先生确实做得很好。我必须使用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')
Run Code Online (Sandbox Code Playgroud)


coc*_*omo 7

我也在同样的情况下挣扎.最后,我使用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)
Run Code Online (Sandbox Code Playgroud)

请用适当的PIL操作替换"打开图像"操作.


cyb*_*ast 7

事实证明,烧瓶提供了一个解决方案(rtm给自己!):

from flask import abort, send_file
try:
    return send_file(image_file)
except:
    abort(404)
Run Code Online (Sandbox Code Playgroud)