How to send image generated by PIL to browser?
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 ?
Solution 1:
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:
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:
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:
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)