ImageFile is the plumbing underneath Image.open. Most code never touches it, but three things in it come up often enough to be worth knowing.
ImageFile.Parser lets you feed bytes in as they arrive rather than handing over a complete file. Useful for a download in progress, a socket, or a file you would rather not hold in memory all at once.
from PIL import ImageFile
parser = ImageFile.Parser()
with open("photo.jpg", "rb") as fp:
while True:
chunk = fp.read(4096)
if not chunk:
break
parser.feed(chunk)
im = parser.close()
print(im.size)
The parser often knows the size long before the whole file has arrived, which is how you check the dimensions of a remote image without downloading all of it.
A file that was cut off mid write raises OSError: image file is truncated. When you would rather have the part that did arrive:
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
ImageFile.MAXBLOCK is the size of the buffer used when writing. Saving a JPEG with a large amount of metadata can fail with encoder error -2, and raising this is the usual fix:
ImageFile.MAXBLOCK = 2 ** 22
from PIL import Image
with Image.open("upload.jpg") as im:
im.verify()
verify checks the file is intact without decoding the pixels. The image object cannot be used afterwards, so open it again to work with it. For anything accepting uploads, check the size before you decode, since a small file can expand into an enormous bitmap.