How to get the format of image with PIL?
Asked Answered
A

2

74

After loading an image file with PIL.Image, how can I determine whether the image file is a PNG/JPG/BMP/GIF? I understand very little about these file formats, can PIL get the format metadata from the file header? Or does it need to 'analyze' the data within the file?

If PIL doesn't provide such an API, is there any python library that does?

Arginine answered 20/9, 2015 at 12:49 Comment(0)
G
120

Try:

from PIL import Image

img = Image.open(filename)
print(img.format)  # 'JPEG'

More info

Graphomotor answered 20/9, 2015 at 12:54 Comment(9)
I guess this attribute is just the file extension, or None if the image is constructed with raw data. The file extension is not always available in my case.Arginine
Please do not guess, but refer to the documentation how the file format is determined. If the PIL reads the image file it must make a choice which decoder is used and this information is exposed through format attribute.Graphomotor
For anyone else coming along... you can get the mimetype by doing Image.MIME[img.format]Son
is there a more lightweight version of this? for instance looking only at the header or metadata instead of opening the image?Northern
You can use imghdr's imghdr.what(filename) function, but it seems to be a bit buggy if extra header info is included in JPEGs (and possibly other formats).Lois
Pillow provides im.get_format_mimetype() for getting image mimetypeCalculating
it returns wrong value for webp, it returns jpeg insteadBiotype
@Biotype smells like a bug, I suggest checking the issue tracker and if the issue does not exist then open a new oneGraphomotor
@claudecomputing You can use python-magic. See pypi.org/project/python-magicBever
C
1

Beware! If the image you are trying to get the format from an image that was created from a copy(), the format will be None.

From the docs

Copies of the image will contain data loaded from the file, but not the file itself, meaning that it can no longer be considered to be in the original format. So if copy() is called on an image, or another method internally creates a copy of the image, then any methods or attributes specific to the format will no longer be present. The fp (file pointer) attribute will no longer be present, and the format attribute will be None.

Methods that create an implicit copy include:

  • convert()
  • crop()
  • remap_palette()
  • resize()
  • reduce()
  • rotate()
  • split()
  • these were all I found as of today, but others may be added

For example:

img = Image.open(filename)
print(img.format)  # 'JPEG'
img2 = img.copy()
print(img.format)  # None
print(img.rotate(90, expand=True).format).  # None

So if you need to get the format from a copy, you need to look to the original image.

Colligan answered 11/10, 2023 at 22:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.