How to send image generated by PIL to browser?
PythonStreamingPython Imaging-LibraryFlaskTemporary FilesPython Problem Overview
I'm using flask for my application. I'd like to send an image (dynamically generated by PIL) to client without saving on disk.
Any idea how to do this ?
Python Solutions
Solution 1 - Python
Here's a version without any temp files and the like (see here):
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')
To use in your code simply do
@app.route('some/route/')
def serve_img():
img = Image.new('RGB', ...)
return serve_pil_image(img)
Solution 2 - Python
Mr. Mr. did an excellent job indeed. I had to use BytesIO() instead of 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')
Solution 3 - Python
First, you can save the image to a tempfile and remove the local file (if you have one):
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)
Second, set the temp file to the response (as per this stackoverflow question):
from flask import send_file
@app.route('/path')
def view_method():
response = send_file(tempFileObj, as_attachment=True, attachment_filename='myfile.jpg')
return response
Solution 4 - Python
It turns out that flask provides a solution (rtm to myself!):
from flask import abort, send_file
try:
return send_file(image_file)
except:
abort(404)
Solution 5 - Python
I was also struggling in the same situation. Finally, I have found its solution using a WSGI application, which is an acceptable object for "make_response" as its argument.
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)
Please replace "opening image" operations with appropriate PIL operations.
Solution 6 - Python
return send_file(fileName, mimetype='image/png')