2012-08-10 6 views
10

Dowiedziałem się, jak korzystać z PIL, aby uzyskać wymiary obrazu, ale nie rozmiar pliku w bajtach. Potrzebuję znać rozmiar pliku, aby zdecydować, czy plik jest zbyt duży, aby go załadować do bazy danych.Jak uzyskać rozmiar obrazu (bajty) przy użyciu PIL

+1

Czy generujesz obraz, czy też obraz jest zapisany na dysku? –

+2

Użyj interfejsu API systemu plików, aby uzyskać rozmiar pliku, a nie PIL. – wberry

+1

lub 'len()', jeśli masz go w pamięci, a nie w systemie plików (co wydaje się prawdopodobne, jeśli przechowujesz się jako BLOB w bazie danych.) – geoffspear

Odpowiedz

14

Spróbuj:

import os 
print os.stat('somefile.ext').st_size 
+0

jest teraz sposób użycia samego PIL? –

+3

Po co używać PIL? – thebjorn

+0

kontrolować, czy jest to obraz, a nie podrobiony nagłówek obrazu, aby utworzyć profil przesyłania, a następnie zapisać go w bazie danych, więc oczywistym jest, aby w PIL uzyskać metodę, aby uzyskać rozmiar w bajtach nie? –

5

jestem trochę późno, ale natknąłem się na to pytanie 5 minut temu, gdy szukają sposobu, aby uzyskać rozmiar obrazu PIL bez zapisywania go na dysku. W przypadku, ktoś napotka to, że jest to prosty sposób to zrobić:

import StringIO 
output = StringIO.StringIO() 
image_output.save(output, 'PNG') #a format needs to be provided 
contents = output.getvalue() 
output.close() 

image_filesize = len(contents) 
5

Jeśli już masz obraz na systemie plików:

import os 
os.path.getsize('path_to_file.jpg')` 

Jeśli jednak chcesz uzyskać zapisany rozmiar obrazu, który znajduje się w pamięci i nie został zapisany w systemie plików:

from io import BytesIO 
img_file = BytesIO() 
image.save(img_file, 'png') 
image_file_size = img_file.tell() 

Ta metoda pozwoli uniknąć wielokrotnego odczytuje dane obrazu jak z StringIO. Zauważ jednak, że użyje więcej pamięci RAM. Wszystko jest kompromisem. :-)

Edit: Właśnie zobaczyłem ten komentarz z PO:

wreszcie, problem jest z beginnig, jeśli ktoś przesłać zdjęcie, które mają 1 giga (kuty jeden) on” Zabij serwer, zanim PIL zrobi swoje rzeczy, więc muszę zablokować żądanie, zanim się zakończy!

To jest bardzo różne pytanie i prawdopodobnie najlepiej wykonać je na serwerze internetowym. W przypadku nginx możesz dodać to do swojej konfiguracji:

http { 
    #... 
     client_max_body_size 100m; # or whatever size you want as your limit 
    #... 
} 
+0

Metoda 'BytesIO' wydaje się niedoszacowywać rozmiaru w porównaniu do rozmiaru z biurka. Każdy pomysł, dlaczego? – getup8