My images are stored in a MongoDB, and I'd like to return them to the client, here is how the code is like:
@app.route("/images/<int:pid>.jpg") def getImage(pid): # get image binary from MongoDB, which is bson.Binary type return image_binary
However, it seems that I can't return binary directly in Flask? My idea so far:
base64of the image binary. The problem is that IE<8 doesn't support this.
Are there better solutions?
Create a response object with the data and then set the content type header. Set the content disposition header to
attachment if you want the browser to save the file instead of displaying it.
@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
You can pass a file-like oject to and the header arguments to
send_file to let it set up the complete response. Use
io.BytesIO for binary data:
return send_file( io.BytesIO(image_binary), mimetype='image/jpeg', as_attachment=True, attachment_filename='%s.jpg' % pid)
Just wanted to confirm that dav1d's second suggestion is correct - I tested this (where obj.logo is a mongoengine ImageField), works fine for 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')
Easier than manually creating a Response object and settings its headers.