Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send image generated by PIL to browser?

People also ask

How do I display PIL images?

Try setting the image format attribute explicitly to . png (i.e. im. format = "PNG" ) before the im. show() call.

How do I save a PIL library image?

save() Saves this image under the given filename. If no format is specified, the format to use is determined from the filename extension, if possible. Keyword options can be used to provide additional instructions to the writer.

How do I import photos from PIL?

To load the image, we simply import the image module from the pillow and call the Image. open(), passing the image filename. Instead of calling the Pillow module, we will call the PIL module as to make it backward compatible with an older module called Python Imaging Library (PIL).


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)

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')

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

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)

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.