Rozumiem, że możesz uzyskać rozmiar obrazu za pomocą PIL w następujący sposób
from PIL import Image
im = Image.open(image_filename)
width, height = im.size
Chciałbym jednak uzyskać szerokość i wysokość obrazu bez konieczności ładowania obrazu do pamięci. Czy to jest możliwe? Robię tylko statystyki dotyczące rozmiarów obrazów i nie dbam o zawartość obrazu. Chcę tylko przyspieszyć przetwarzanie.
python
image
image-processing
Sami A. Haija
źródło
źródło
.open()
odczytuje cały plik do pamięci ... (to właśnie.load()
) robi - o ile wiem - jest tak dobre, jak to tylko możliwePIL
pmap
do monitorowania pamięci używanej przez proces pokazuje mi, że rzeczywiściePIL
nie ładuje całego obrazu do pamięci.Odpowiedzi:
Jak wskazują komentarze, PIL nie ładuje obrazu do pamięci podczas wywoływania
.open
. Patrząc na dokumenty zPIL 1.1.7
, dokumentacja.open
mówi:W źródle jest kilka operacji na plikach, takich jak:
ale to prawie nie stanowi przeczytania całego pliku. W rzeczywistości
.open
po pomyślnym zakończeniu zwraca obiekt pliku i nazwę pliku. Ponadto doktorzy mówią:Kopiąc głębiej, widzimy, że
.open
wywołania_open
są przeciążeniem specyficznym dla formatu obrazu. Każdą z implementacji_open
można znaleźć w nowym pliku, np. Pliki .jpeg są w formacieJpegImagePlugin.py
. Przyjrzyjmy się temu szczegółowo.Tutaj sprawy wydają się nieco skomplikowane, w tym jest nieskończona pętla, która zostaje zerwana po znalezieniu znacznika jpeg:
Wygląda na to, że mógłby odczytać cały plik, gdyby był źle sformułowany. Jeśli jednak odczyta znacznik informacyjny OK, powinien wybuchnąć wcześnie. Funkcja
handler
ostatecznie ustalaself.size
wymiary obrazu.źródło
open
uzyskuje rozmiar obrazu, czy też jest to leniwa operacja? A jeśli jest leniwy, czy odczytuje dane obrazu w tym samym czasie?Docs/PIL.Image.html
..jpeg
Format wygląda OK, dopóki główka została znaleziona.Jeśli nie dbasz o zawartość obrazu, PIL jest prawdopodobnie przesadą.
Proponuję przeanalizować dane wyjściowe modułu magicznego Pythona:
Jest to opakowanie wokół libmagic, które odczytuje jak najmniej bajtów, aby zidentyfikować sygnaturę typu pliku.
Odpowiednia wersja skryptu:
https://raw.githubusercontent.com/scardine/image_size/master/get_image_size.py
[aktualizacja]
Wygląda na to, że pliki JPEG są odporne na magię. :-)
Rozumiem dlaczego: aby uzyskać wymiary obrazu dla plików JPEG, być może będziesz musiał przeczytać więcej bajtów, niż lubi czytać libmagic.
Podwinąłem rękawy i przyszedłem z tym bardzo nieprzetestowanym fragmentem (pobierz go z GitHub), który nie wymaga modułów innych firm.
[aktualizacja 2019]
Sprawdź implementację Rusta: https://github.com/scardine/imsz
źródło
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x89 in position 0: invalid start byte
na MacOS, python3 nadata = input.read(25)
,file
na obrazie dajePNG image data, 720 x 857, 8-bit/color RGB, non-interlaced
Na pypi jest pakiet o nazwie,
imagesize
który obecnie działa dla mnie, chociaż nie wygląda na bardzo aktywny.Zainstalować:
Stosowanie:
Strona domowa: https://github.com/shibukawa/imagesize_py
PyPi: https://pypi.org/project/imagesize/
źródło
Często pobieram rozmiary obrazów w Internecie. Oczywiście nie można pobrać obrazu, a następnie załadować go w celu przeanalizowania informacji. To zbyt czasochłonne. Moja metoda polega na podawaniu fragmentów do kontenera obrazu i sprawdzaniu, czy za każdym razem może on przeanalizować obraz. Zatrzymaj pętlę, gdy otrzymam potrzebne informacje.
Wyodrębniłem rdzeń mojego kodu i zmodyfikowałem go, aby analizować pliki lokalne.
Wynik:
Rzeczywisty rozmiar pliku to 1 543 580 bajtów, a do uzyskania rozmiaru obrazu wystarczy odczytać tylko 38 912 bajtów. Mam nadzieję, że to pomoże.
źródło
Kolejny krótki sposób na zrobienie tego w systemach uniksowych. Zależy to od wyjścia,
file
którego nie jestem pewien, jest znormalizowane we wszystkich systemach. To prawdopodobnie nie powinno być używane w kodzie produkcyjnym. Ponadto większość plików JPEG nie podaje rozmiaru obrazu.źródło
IndexError: list index out of range
Ta odpowiedź ma inną dobrą rozdzielczość, ale brakuje formatu pgm . Ta odpowiedź rozwiązała problem pgm . I dodaję bmp .
Kody są poniżej
źródło
imghdr
jednak radzi sobie z niektórymi jpegami dość słabo.