tagkit.image.exif¶
EXIF image handling functionality.
This module provides classes for reading, modifying, and removing EXIF tags from image files.
Module Contents¶
Classes¶
Handler for reading, modifying, and removing EXIF tags from a single image file. |
Data¶
API¶
- tagkit.image.exif.DATETIME_TAG_PRECEDENCE = ['DateTimeOriginal', 'DateTimeDigitized', 'DateTime']¶
- class tagkit.image.exif.ExifImage(file_path: tagkit.core.types.FilePath, tag_filter: Optional[Iterable[Union[int, str]]] = None, thumbnail: Optional[bool] = None, ifd: Optional[tagkit.core.types.IfdName] = None, io_backend: Optional[tagkit.tag_io.base.ExifIOBackend] = None)¶
Handler for reading, modifying, and removing EXIF tags from a single image file.
- Args:
file_path: Path to the image file. tag_filter: Optional list of tag names or IDs to filter by thumbnail: If True, use thumbnail IFD ifd: Specific IFD to use io_backend: Custom backend for EXIF IO. Defaults to piexif.
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.tags['Make'] ExifTag(id=271, value='Tagkit', ifd='IFD0')
Initialization
- __len__() int¶
Return the number of tags in this image.
- write_tag(tag_key: Union[str, int], value: tagkit.core.types.TagValue, ifd: Optional[tagkit.core.types.IfdName] = None)¶
Set the value of a specific EXIF tag.
- Args:
tag_key: Tag name or tag ID. value: Value to set. ifd: Specific IFD to use.
- Raises:
KeyError: If the tag is not found. ValueError: If the tag or IFD is invalid.
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.write_tag('Artist', 'John Doe', ifd='IFD0')
- write_tags(tags: Mapping[Union[str, int], tagkit.core.types.TagValue], ifd: Optional[tagkit.core.types.IfdName] = None)¶
Set multiple EXIF tags at once.
- Args:
tags: A dictionary mapping tag names or IDs to values. ifd: Specific IFD to use for all tags (overrides default logic).
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.write_tags({'Artist': 'Jane', 'Copyright': '2025 John'})
- delete_tag(tag_key: Union[str, int], ifd: Optional[tagkit.core.types.IfdName] = None)¶
Remove a specific EXIF tag if it exists.
- Args:
tag_key: Tag name or tag ID. ifd: Specific IFD to use.
- Raises:
ValueError: If the tag or IFD is invalid.
- Example:
>>> exif = ExifImage('image10.jpg') >>> exif.delete_tag('Make', ifd='IFD0')
- delete_tags(tag_keys: Iterable[Union[str, int]], ifd: Optional[tagkit.core.types.IfdName] = None)¶
Remove multiple EXIF tags at once.
- Args:
tag_keys: A list of tag names or tag IDs to remove. ifd: Specific IFD to use for all tags (overrides default logic).
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.delete_tags(['Artist', 'Copyright'])
- read_tag(tag_key: Union[str, int], ifd: Optional[tagkit.core.types.IfdName] = None, format_value: bool = False, binary_format: Optional[str] = None) tagkit.core.types.TagValue¶
Read the value of a specific EXIF tag.
- Args:
tag_key: Tag name or tag ID. ifd: Specific IFD to use. format_value: If True, return formatted string value; if False, return raw value. binary_format: How to format binary data - ‘bytes’, ‘hex’, or ‘base64’. Only used when format_value=True.
- Returns:
The tag value (formatted or raw depending on format_value parameter).
- Raises:
TagNotFound: If the tag is not present in the image. InvalidTagName, InvalidTagId: If the provided tag name or id is invalid. ValueError: If the tag or IFD is invalid or if binary_format is unsupported.
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.read_tag('Make') 'Tagkit' >>> exif.read_tag('Make', format_value=False) 'Tagkit'
- read_tags(tag_keys: list[Union[str, int]], ifd: Optional[tagkit.core.types.IfdName] = None, format_value: bool = False, binary_format: Optional[str] = None, skip_missing: bool = False) dict[str, tagkit.core.types.TagValue]¶
Read multiple EXIF tags at once.
- Args:
tag_keys: A list of tag names or tag IDs to read. ifd: Specific IFD to use for all tags (overrides default logic). format_value: If True, return formatted string values; if False, return raw values. binary_format: How to format binary data - ‘bytes’, ‘hex’, or ‘base64’. Only used when format_value=True. skip_missing: If True, skip tags that are not present in the image. If False, raise TagNotFound if any tag is missing.
- Returns:
A dictionary mapping tag names to their values. Only tags that exist in the image are included in the result.
- Example:
>>> exif = ExifImage('image1.jpg') >>> exif.read_tags(['Make', 'Model']) {'Make': 'Tagkit', 'Model': 'Tagkit Camera'}
- property tags: Mapping[str, tagkit.core.tag.ExifTag]¶
Get the filtered tags based on tag_filter and ifd settings.
- Returns:
dict: A dictionary of filtered tags with tag names as keys.
- save(create_backup: bool = False)¶
Write the modified EXIF data back to the image file.
- Raises:
IOError: If writing to the file fails.
- as_dict(binary_format: Optional[str] = None) dict[str, dict[str, Union[str, int]]]¶
Convert the image data to a nested dictionary structure.
- Args:
- binary_format: How to format binary data - ‘bytes’, ‘hex’, or ‘base64’
If None, <bytes: N> will be shown as a placeholder.
- Returns:
dict: A nested dictionary containing the EXIF data for the image.
- Example:
>>> exif = ExifImage('image2.jpg') >>> exif.as_dict() {'Make': {'id': 271, 'value': 'Tagkit', 'ifd': 'IFD0'}, 'DateTime': {'id': 306, 'value': '2025:05:02 14:30:00', 'ifd': 'IFD0'}}
- get_datetime(tag: Optional[str] = None) datetime.datetime¶
Get datetime from EXIF tags.
By default, uses precedence order: DateTimeOriginal > DateTimeDigitized > DateTime. Can also retrieve a specific datetime tag.
- Args:
tag: Optional specific datetime tag name to retrieve
- Returns:
datetime: datetime object for image.
- Raises:
DateTimeError: If a datetime tag is found but cannot be parsed. TagNotFound: If no datetime tags are found. InvalidTagName: If the provided tag name is invalid.
- Examples:
>>> exif = ExifImage('image1.jpg') >>> dt = exif.get_datetime() >>> print(dt) 2025-05-01 14:30:00
>>> dt = exif.get_datetime(tag='DateTimeOriginal') >>> print(dt) 2025-05-01 14:30:00
- set_datetime(dt: datetime.datetime, tags: Optional[Iterable[str]] = None) None¶
Set datetime EXIF tags (in-memory, not saved until save() is called).
By default, updates all three datetime tags (DateTime, DateTimeOriginal, DateTimeDigitized) to ensure consistency. Can optionally specify which tags to update.
- Args:
dt: Datetime object to set. tags: Optional list of specific datetime tag names to update. If None, updates all three datetime tags. Valid values are ‘DateTime’, ‘DateTimeOriginal’, ‘DateTimeDigitized’
- Examples:
>>> from datetime import datetime >>> exif = ExifImage('image1.jpg') >>> exif.set_datetime(datetime(2025, 6, 15, 10, 30, 0)) >>> exif.save()
>>> # Update only specific tags >>> exif.set_datetime( ... datetime(2025, 6, 15, 10, 30, 0), ... tags=['DateTimeOriginal'], ... ) >>> exif.save()
- offset_datetime(delta: datetime.timedelta, tags: Optional[Iterable[str]] = None) None¶
Offset datetime EXIF tags by a timedelta (in-memory, not saved until save() is called).
Adds (or subtracts if negative) a timedelta to existing datetime tags. By default, offsets all present datetime tags.
- Args:
delta: Timedelta to add to existing datetime values. tags: Optional list of specific datetime tag names to offset. If None, offsets all present datetime tags. Valid values are ‘DateTime’, ‘DateTimeOriginal’, ‘DateTimeDigitized’
- Raises:
DateTimeError: If a datetime tag is found but cannot be parsed.
- Examples:
>>> from datetime import timedelta >>> exif = ExifImage('image1.jpg') >>> exif.offset_datetime(timedelta(hours=2)) >>> exif.save()
>>> # Offset only specific tag >>> exif.offset_datetime(timedelta(days=-1), tags=['DateTimeOriginal']) >>> exif.save()
- get_all_datetimes() dict[str, datetime.datetime]¶
Get all datetime EXIF tags from the image.
Returns a dictionary mapping tag names to datetime objects for all datetime-related EXIF tags that are present.
- Returns:
Dictionary mapping tag names to datetime objects. Only includes tags that are present in the image.
- Raises:
DateTimeError: If a datetime tag is found but cannot be parsed.
- Examples:
>>> exif = ExifImage('image1.jpg') >>> datetimes = exif.get_all_datetimes() >>> for tag_name, dt in datetimes.items(): ... print(f"{tag_name}: {dt}") DateTimeOriginal: 2025-05-01 14:30:00 DateTime: 2025-05-01 14:30:00