Skip to content

Possible to add an IFD to an image's EXIF data? #8229

@tegandbiscuits

Description

@tegandbiscuits

(apologies if I'm using wrong/weird terminology)

I'm trying to add EXIF tags to an image that doesn't initially have any. Some of the tags I'm trying to set belong to IFD.Exif . When I run img.getexif().get_ifd(IFD.Exif) I get back an empty dict that doesn't persist anything I try to add to it.

However if the image already has data for IFD.Exif (so img.getexif().get_ifd(IFD.Exif) isn't {}) then I'm able to manipulate it as expected.

I'm not super familiar with how EXIF data works at a technical level, but I think I'm missing something that I need to do/set to
the image before I can set the tags I want to set. But I'm not 100% sure if that's the case, and if can I do it with Pillow?

What are your OS, Python and Pillow versions?

  • OS: macOS 14.5
  • Python: 3.12.4
  • Pillow: 10.3.0
--------------------------------------------------------------------
Pillow 10.3.0
Python 3.12.4 (main, Jun 27 2024, 18:40:44) [Clang 15.0.0 (clang-1500.3.9.4)]
--------------------------------------------------------------------
Python executable is /Users/tegan/Library/Caches/pypoetry/virtualenvs/exifmate-Hu18rg69-py3.12/bin/python3
Environment Python files loaded from /Users/tegan/Library/Caches/pypoetry/virtualenvs/exifmate-Hu18rg69-py3.12
System Python files loaded from /Users/tegan/.pyenv/versions/3.12.4
--------------------------------------------------------------------
Python Pillow modules loaded from /Users/tegan/Library/Caches/pypoetry/virtualenvs/exifmate-Hu18rg69-py3.12/lib/python3.12/site-packages/PIL
Binary Pillow modules loaded from /Users/tegan/Library/Caches/pypoetry/virtualenvs/exifmate-Hu18rg69-py3.12/lib/python3.12/site-packages/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 10.3.0
*** TKINTER support not installed
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.3.2
--- WEBP Transparency support ok
--- WEBPMUX support ok
--- WEBP Animation support ok
--- JPEG support ok, compiled for libjpeg-turbo 3.0.2
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.2
--- ZLIB (PNG/ZIP) support ok, loaded 1.3.1
--- LIBTIFF support ok, loaded 4.6.0
*** RAQM (Bidirectional Text) support not installed
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------

Sample Code

from PIL.TiffImagePlugin import IFDRational
from PIL.ExifTags import IFD
from PIL import Image

tag_id = 33434 # exposure time tag
exposure_time = IFDRational(1/500)

# behavior with existing EXIF data
img_one = Image.open("has-exif.jpg")
exif_one = img_one.getexif()
exif_one.get_ifd(IFD.Exif)[tag_id] = exposure_time
assert exif_one.get_ifd(IFD.Exif)[tag_id] == exposure_time

# saving the image with the modified data also works
# img_one.save("has-exif.jpg", exif=exif_one)

# behavior with no existing EXIF data
img_two = Image.open("no-exif.jpg")
exif_two = img_two.getexif() # presumably this is basically the same as `Image.Exif()`
assert exif_two.get_ifd(IFD.Exif) == {}
exif_two.get_ifd(IFD.Exif)[tag_id] = exposure_time

# these assertions pass but I expect them both to fail
assert exif_two.get_ifd(IFD.Exif) == {}
assert exif_two.get_ifd(IFD.Exif).get(tag_id) == None

sample pictures.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions