65 votes

Comment envoyer l'image générée par la LIP au navigateur ?

J'utilise Flask pour mon application. J'aimerais envoyer une image (générée dynamiquement par PIL) au client sans la sauvegarder sur le disque.

Comment faire ?

178voto

Mr. Mr. Points 987

Voici une version sans fichiers temporaires et autres (cf. aquí ):

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

Pour l'utiliser dans votre code, il suffit de faire

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

28voto

Dan Erez Points 343

Monsieur a en effet fait un excellent travail. J'ai dû utiliser BytesIO() au lieu de 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')

21voto

Adam Points 2669

Tout d'abord, vous pouvez enregistrer l'image dans un fichier fichier temporaire et supprimer le fichier local (si vous en avez un) :

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)

Deuxièmement, définissez le fichier temporaire à la réponse (comme dans cette question de 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

7voto

cybertoast Points 560

Il s'avère que flask fournit une solution (rtm à moi-même !):

from flask import abort, send_file
try:
    return send_file(image_file)
except:
    abort(404)

6voto

cocoatomo Points 888

Je me débattais également dans la même situation. Finalement, j'ai trouvé sa solution en utilisant une application WSGI, qui est un objet acceptable pour "make_response" comme 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)

Veuillez remplacer les opérations d'"ouverture de l'image" par des opérations de DIP appropriées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X