2013-01-15 16 views
15

Jeśli użytkownik przesyła obraz, a zmieniam go za pomocą PIL, otrzymuję numer PIL Image object.Jak wyświetlić obiekt obrazu PIL w szablonie?

Jak wyświetlić plikw szablonie, zanim zostanie zapisany w bazie danych? Czy można go nawet przekazać jako obraz i wyrenderować?

+1

Czy na pewno chcesz wyświetlić obraz bezpośrednio z procesu Django?Nie tylko zużyje cenną pamięć, ale również utworzy jeden wątek lub przetworzy się –

+1

(bez żadnych mocnych dowodów). Myślę, że znacznie lepiej oszczędzasz obraz i pozwalasz serwerowi front-end wykonać bajt-shuffling dla ciebie. Spójrz na X-Sendfile (Apache) lub X-Accel-Redirect (Nginx). –

Odpowiedz

13

W przypadku ograniczonego zestawu przeglądarek można kodować obraz metodą base64 i używać obrazów śródliniowych. Zobacz Embedding Base64 Images.

Rozwiązaniem, które działa we wszystkich przeglądarkach, jest tag obrazu odnoszący się do view that returns the image.

[aktualizacja]

Wszystko czego chcę to, aby użytkownik mógł przesłać oryginalny obraz, a następnie poprosi o innej formie do wejścia podpis do obrazka (ze zmienionym rozmiarze do lewej strony pole podpisu). Następnie, gdy użytkownik trafi "prześlij" obraz, a podpis zostanie zapisany w instancji modelu.

Cóż ... Gdy używasz <img src="foo">, Foo jest zawsze pobierany przez GET może dlatego nie działa - request.FILES nie będzie dostępny na żądanie GET. Jeśli otworzysz firebuga lub pasek narzędzi do debugowania chrome, na karcie sieci zobaczysz żądanie POST z przesłanym obrazem, a następnie żądanie GET, aby pobrać obraz.

Musisz zapisać obraz pomiędzy krokami.

Jak inaczej mogę go zapisać? Chciałbym, żeby to było tymczasowe. Czy uważasz, że jest to naprawdę łatwy sposób, czy powinienem przyjrzeć się tym opcjom?

Popularne opcje to redis i memcached. Możesz myśleć o nich jako o gigantycznym wspólnym python-dict z datą wygaśnięcia. Jeśli obrazy są małe, podobnie jak awatar, można również zapisać dane obrazu w zmiennej sesji.

+0

Jak mogę odwołać się do widoku z tagu obrazu? – sgarza62

+1

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

+0

Dziękuję za pomoc, przepraszam za opóźnienie ... Próbowałem uruchomić to z moim kodem. Byłem w stanie zapisać 'Obraz' na obiekcie' HttpResponse' (dzięki!), Ale mam problem z uruchomieniem go z tagu obrazu w szablonie. Może nie przekazuję jakiegoś parametru w adresie URL, nie jestem pewien. – sgarza62

6

Możesz osadzić obrazy kodowane base64 w tagu. Więc możesz przekonwertować obraz PIL na base64, a następnie go wyświetlić.

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] 

Następnie pokazać z:

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

spojrzeniem na example output.

+0

To działało dla mnie po usunięciu tej linii: contents = contents.split ('\ n') [0] – Yerke

14

Tak i nie.

Tak, możesz umieścić obrazy jako surowe dane Base64. Oto mały skrypt, który można przetestować:

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

Jest to jednak bardzo zły pomysł. Dzięki wielu miniaturom Twoja pojedyncza strona HTML może mieć 10 MB +.

To, co naprawdę należy robić, to używanie osobnego widoku Django do zwracania obrazów z obiektów PIL jako plików PNG, a następnie odwoływanie się do tego widoku w atrybutach imghref na twojej stronie.

Powiązane problemy