2013-01-15 17 views
15

Nếu người dùng tải lên hình ảnh và tôi đổi kích thước hình ảnh bằng PIL, tôi nhận được PIL Image object.Làm cách nào để hiển thị đối tượng Hình ảnh PIL trong mẫu?

Làm cách nào để hiển thị tệp PIL Image trong mẫu, trước khi tệp được lưu vào cơ sở dữ liệu? Thậm chí nó có thể được chuyển thành một hình ảnh và được hiển thị không?

+1

Bạn có chắc chắn muốn phục vụ hình ảnh trực tiếp từ quá trình Django của mình không?Không chỉ nó sẽ tiêu thụ bộ nhớ quý giá, nó cũng sẽ buộc một sợi hoặc quá trình –

+1

(Không có bất kỳ bằng chứng cứng) Tôi nghĩ rằng bạn tốt hơn nhiều để tiết kiệm hình ảnh và để cho máy chủ web front-end làm các byte-shuffling cho bạn. Hãy xem X-Sendfile (Apache) hoặc X-Accel-Redirect (Nginx). –

Trả lời

13

Đối với một bộ trình duyệt giới hạn, bạn có thể mã hóa base64 hình ảnh và sử dụng hình ảnh nội dòng. Xem Embedding Base64 Images.

Giải pháp hoạt động cho tất cả các trình duyệt là thẻ hình ảnh tham chiếu view that returns the image.

[cập nhật]

Tất cả tôi muốn là cho người sử dụng gửi ảnh ban đầu, và sau đó được thúc đẩy bởi một hình thức để nhập chú thích cho hình ảnh (với hình ảnh thay đổi kích cỡ để bên trái của trường chú thích). Sau đó, khi người dùng nhấn "gửi" hình ảnh và chú thích được lưu trong một cá thể mô hình.

Vâng ... Khi bạn sử dụng <img src="foo">, foo luôn được truy xuất bằng GET có lẽ đó là lý do tại sao nó không hoạt động - request.FILES sẽ không có sẵn trong yêu cầu GET. Nếu bạn mở firebug hoặc thanh công cụ gỡ lỗi chrome, trong tab mạng, bạn sẽ thấy yêu cầu POST với hình ảnh đã tải lên và sau đó là yêu cầu GET để tìm nạp hình ảnh.

Bạn phải lưu hình ảnh ở đâu đó giữa cả hai bước.

Tôi có thể lưu nó bằng cách nào khác? Tôi rất thích vì nó là tạm thời. Bạn có nghĩ rằng có một cách thực sự dễ dàng để làm điều này, hay tôi nên đi vào các tùy chọn đó?

Lựa chọn phổ biến là redismemcached. Bạn có thể nghĩ về chúng như dict được chia sẻ khổng lồ với một ngày hết hạn. Nếu hình ảnh nhỏ, giống như hình đại diện, bạn cũng có thể lưu dữ liệu hình ảnh trong biến phiên.

+0

Tôi làm cách nào để tham chiếu chế độ xem từ thẻ hình ảnh? – sgarza62

+1

'the same url from urls.py, got it?' –

+0

Cảm ơn bạn đã giúp bạn cho đến nay, tôi xin lỗi vì sự chậm trễ ... Tôi đã cố gắng để có được điều này để làm việc với mã của tôi. Tôi đã có thể lưu 'Hình ảnh' vào đối tượng' HttpResponse' (cảm ơn!), Nhưng tôi đang gặp khó khăn khi làm cho nó hoạt động từ thẻ hình ảnh trong mẫu. Có lẽ tôi không đi qua một tham số nào đó trong url, tôi không chắc chắn. – sgarza62

6

Bạn có thể nhúng hình ảnh được mã hóa base64 vào thẻ. Vì vậy, bạn có thể chuyển đổi hình ảnh PIL thành base64 và sau đó hiển thị nó.

from PIL import Image 
import StringIO 

x = Image.new('RGB',(400,400)) 
output = StringIO.StringIO() 
x.save(output, "PNG") 
contents = output.getvalue().encode("base64") 
output.close() 
contents = contents.split('\n')[0] 

Sau đó hiển thị với:

<img src="data:image/png;base64,' + contents + ' /> 

Nhìn đến một example output.

+0

Điều này làm việc cho tôi sau khi tôi xóa dòng này: contents = contents.split ('\ n') [0] – Yerke

14

Có và không.

Có, bạn có thể đặt hình ảnh làm dữ liệu Base64 thô. Dưới đây là một tập lệnh nhỏ mà bạn có thể sử dụng để kiểm tra điều này:

import Image 
import base64 
import StringIO 
output = StringIO.StringIO() 
im = Image.open("test.png") # Your image here! 
im.save(output, format='PNG') 
output.seek(0) 
output_s = output.read() 
b64 = base64.b64encode(output_s) 
open("test.html","w+").write('<img src="data:image/png;base64,{0}"/>'.format(b64)) 

Tuy nhiên, đây thực sự là một ý tưởng tồi. Với nhiều hình thu nhỏ, trang HTML đơn của bạn có thể là 10MB +.

Điều bạn thực sự cần làm là sử dụng chế độ xem Django riêng biệt để trả lại hình ảnh từ đối tượng PIL dưới dạng tệp PNG và sau đó tham chiếu chế độ xem đó trong thuộc tính imghref trên trang của bạn.