2012-06-13 46 views
37

hình ảnh của tôi được lưu trữ trong MongoDB, tôi muốn trả lại cho khách hàng, đây là cách mã giống như:bình được tạo ra từ cơ sở dữ liệu

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

Tuy nhiên, có vẻ như tôi có thể' t trả về nhị phân trực tiếp trong Flask?

Dưới đây là những gì tôi đã đưa ra bây giờ:

  1. bù lại base64 của nhị phân hình ảnh. -> IE < 8 không hỗ trợ tính năng này.
  2. tạo tệp tạm thời rồi trả lại bằng send_file.

Có giải pháp nào tốt hơn không?

+1

bản sao có thể có của [Cách trả lại hình ảnh trong phản hồi bình?] (Http://stackoverflow.com/questions/8637153/how-to-return-images-in-flask-response) – erickrf

Trả lời

70

Tạo đối tượng phản hồi với dữ liệu và sau đó đặt tiêu đề loại nội dung. Đặt tiêu đề sắp xếp nội dung thành attachment nếu bạn muốn trình duyệt lưu tệp thay vì hiển thị nó.

@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 

liên quan: werkzeug.Headersflask.Response

Bạn có thể vượt qua một oject tập tin giống như đến và các đối số tiêu đề để send_file để cho nó thành lập đáp ứng hoàn toàn. Sử dụng io.BytesIO cho dữ liệu nhị phân:

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

Send_file có đóng đối tượng tệp không Sau khi gửi? Nếu nó không phải là một BytesIO, nhưng một số đối tượng tập tin khác mà không yêu cầu một cuộc gọi để đóng(), ai sẽ gọi nó? – baruch

+1

Sử dụng Python 3 và Flask 0.12, việc cung cấp chuỗi nhị phân ('b ''') có thể dẫn đến 'UnicodeError'. 'send_file()' có thể tốt hơn. – GergelyPolonkai

32

Chỉ muốn xác nhận đề nghị thứ hai của dav1d đó là đúng - Tôi đã thử nghiệm này (trong đó một ImageField mongoengine obj.logo là), hoạt động tốt đối với tôi:

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

Dễ dàng hơn tạo thủ công đối tượng Response và cài đặt các tiêu đề của nó.

+0

Đây là những gì tôi đang tìm kiếm. – pangeacake

Các vấn đề liên quan