Comment envoyer une image générée par PIL au navigateur?
j'utilise un flacon pour mon application. J'aimerais envoyer une image (générée dynamiquement par PIL) au client sans la sauvegarder sur le disque.
une idée de comment faire cela ?
4 réponses
tout D'abord, vous pouvez enregistrer l'image dans un tempfile 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, réglez le fichier temp à la réponse (selon cette question de débordement de Stac ):
from flask import send_file
@app.route('/path')
def view_method():
response = send_file(tempFileObj, as_attachment=True, attachment_filename='myfile.jpg')
return response
Voici une version SANS fichier temp et similaire (voir ici ):
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')
à utiliser dans votre code simplement faire
@app.route('some/route/')
def serve_img():
img = Image.new('RGB', ...)
return serve_pil_image(img)
je me débattais aussi dans la même situation. Enfin, 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)
remplacer les opérations" image d'ouverture " par les opérations PIL appropriées.
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)