5thAveApe
5thAveApe

Reputation: 31

Getting "'NoneType' object has no attribute 'items'" error with PIL library

Code:

#!/usr/bin/python3

from PIL import Image, ExifTags

img = Image.open("/root/Bilder/sysPics/schwarz-weiß-Karte.jpg")

for i, j in img._getexif().items():
    if i in ExifTags.TAGS:
        print(ExifTags.TAGS[i] + " - " + str(j))

Error:

Traceback (most recent call last):
  File "python-tool.py", line 7, in <module>
    for i, j in img._getexif().items():
AttributeError: 'NoneType' object has no attribute 'items'

Can anyone help me? I never worked with the PIL lib but I saw a tutorial, in which this .items() method worked:

https://www.youtube.com/watch?v=-PiR5SX4Mxo&list=PLNmsVeXQZj7onbtIXvxZTzeKGnzI6NFp_&index=8

There is no difference between his code and mine, I can't believe they cut off the .items() method in the last patches.

Upvotes: 3

Views: 3418

Answers (1)

Gino Mempin
Gino Mempin

Reputation: 29670

1st, you should not be relying on internal functions such as _get_exif() because their implementation can change at any time and they are usually not meant for public use. (See _single_leading_underscore from PEP8 naming conventions).

2nd, you should consider that not all images have EXIF data. It’s possible that trying to get the EXIF data will None. So it's not the .items() method that's the problem, rather it's that your _get_exif() returned None. Your code does not have handling for that case, you are always assuming _get_exif() returns a dict.

Now, to solve your problem, for Python3.x (I have Python3.6.8) and PIL (installed as Pillow, Pillow==6.0.0), the Image object now provides a public getexif() method that you can use. The return type is None if the image has no EXIF data or a <class 'PIL.Image.Exif'>.

from PIL import Image, ExifTags

img = Image.open("sample.jpg")
print(dir(img))
# [... 'getexif' ...]

img_exif = img.getexif()
if img_exif:
    print(type(img_exif))
    # <class 'PIL.Image.Exif'>
    print(dict(img_exif))
    # { .. 271: 'FUJIFILM', 305: 'Adobe Photoshop Lightroom 6.14 (Macintosh)', }

    img_exif_dict = dict(img_exif)
    for key, val in img_exif_dict.items():
        if key in ExifTags.TAGS:
            print(ExifTags.TAGS[key] + " - " + str(val))
else:
    print("Sorry, image has no exif data.")

Upvotes: 4

Related Questions