2012-06-13 12 views
37

mie immagini sono memorizzate in MongoDB, vorrei restituirli al client, ecco come il codice è simile:pallone creato dal database

@app.route("/images/<int:pid>.jpg") 
def getImage(pid): 
    # get image binary from MongoDB, which is bson.Binary type 
    return image_binary 

Tuttavia, sembra che posso' t restituire il binario direttamente in Flask?

Ecco quello che mi si avvicinò con la società:

  1. ritorno Base64 del binario dell'immagine. -> IE < 8 non supporta questo.
  2. creare un file temporaneo quindi restituirlo con send_file.

Esistono soluzioni migliori?

+1

possibile duplicato di [Come restituire immagini in risposta pallone?] (Http://stackoverflow.com/questions/8637153/how-to-return-images-in-flask-response) – erickrf

risposta

70

Creare un oggetto risposta con i dati e quindi impostare l'intestazione del tipo di contenuto. Impostare l'intestazione di disposizione del contenuto su attachment se si desidera che il browser salvi il file anziché visualizzarlo.

@app.route('/images/<int:pid>.jpg') 
def get_image(pid): 
    image_binary = read_image(pid) 
    response = make_response(image_binary) 
    response.headers.set('Content-Type', 'image/jpeg') 
    response.headers.set(
     'Content-Disposition', 'attachment', filename='%s.jpg' % pid) 
    return response 

Rilevante: werkzeug.Headers e flask.Response

È possibile passare un ogetto simile a file da e per gli argomenti di intestazione per send_file di lasciarlo impostare la risposta completa. Utilizzare io.BytesIO per dati binari:

return send_file(
    io.BytesIO(image_binary), 
    mimetype='image/jpeg', 
    as_attachment=True, 
    attachment_filename='%s.jpg' % pid) 
+0

Fa send_file chiudere l'oggetto file dopo l'invio? Se non è un BytesIO, ma qualche altro oggetto file che richiede una chiamata a close(), chi la chiamerà? – baruch

+1

L'uso di Python 3 e Flask 0.12, fornendo una stringa binaria ('b ''') può causare un 'errore Unicode'. 'send_file()' potrebbe essere solo migliore. – GergelyPolonkai

32

Volevo solo per confermare la seconda ipotesi che di dav1d è corretta - Ho provato questo (dove obj.logo è un ImageField mongoengine), funziona bene per me:

import io 

from flask import current_app as app 
from flask import send_file 

from myproject import Obj 

@app.route('/logo.png') 
def logo(): 
    """Serves the logo image.""" 

    obj = Obj.objects.get(title='Logo') 

    return send_file(io.BytesIO(obj.logo.read()), 
        attachment_filename='logo.png', 
        mimetype='image/png') 

Più semplice della creazione manuale di un oggetto Risposta e impostazioni delle intestazioni.

+0

Questo era quello che stavo cercando. – pangeacake