Jak wskazują komentarze, PIL nie ładuje obrazu do pamięci podczas wywoływania .open
. Patrząc na dokumenty z PIL 1.1.7
, dokumentacja .open
mówi:
def open(fp, mode="r"):
"Open an image file, without loading the raster data"
W źródle jest kilka operacji na plikach, takich jak:
...
prefix = fp.read(16)
...
fp.seek(0)
...
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ą:
otwórz (plik, tryb = ”r”)
Otwiera i identyfikuje podany plik obrazu.
To jest leniwa operacja; ta funkcja identyfikuje plik, ale rzeczywiste dane obrazu nie są odczytywane z pliku, dopóki nie spróbujesz przetworzyć danych (lub wywołasz metodę ładowania ).
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 formacie JpegImagePlugin.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:
while True:
s = s + self.fp.read(1)
i = i16(s)
if i in MARKER:
name, description, handler = MARKER[i]
# print hex(i), name, description
if handler is not None:
handler(self, i)
if i == 0xFFDA: # start of scan
rawmode = self.mode
if self.mode == "CMYK":
rawmode = "CMYK;I" # assume adobe conventions
self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
# self.__offset = self.fp.tell()
break
s = self.fp.read(1)
elif i == 0 or i == 65535:
# padded marker or junk; move on
s = "\xff"
else:
raise SyntaxError("no marker found")
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 ustala self.size
wymiary obrazu.
.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