J'utilise flask pour mon application. Je voudrais envoyer une image (générée dynamiquement par PIL) au client sans enregistrer sur le disque.
Une idée de comment faire ça?
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)
Ensuite, définissez le fichier temporaire sur la réponse (selon 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
Voici une version sans aucun fichier temporaire 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')
Pour utiliser dans votre code, faites simplement
@app.route('some/route/')
def serve_img():
img = Image.new('RGB', ...)
return serve_pil_image(img)
M. M. a effectivement 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')
Je me débattais également 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)
Veuillez remplacer les opérations "image d'ouverture" par des opérations PIL appropriées.
Il s'avère que flask fournit une solution (rtm pour moi-même!):
from flask import abort, send_file
try:
return send_file(image_file)
except:
abort(404)