Added IFD enum

This commit is contained in:
Andrew Murray 2022-11-28 08:39:56 +11:00
parent 72372ad23f
commit 24a5405a9f
4 changed files with 52 additions and 18 deletions

View File

@ -31,6 +31,13 @@ which provide constants and clear-text names for various well-known EXIF tags.
>>> Interop(4096).name >>> Interop(4096).name
'RelatedImageFileFormat' 'RelatedImageFileFormat'
.. py:data:: IFD
>>> from PIL.ExifTags import IFD
>>> IFD.Exif.value
34665
>>> IFD(34665).name
'Exif'
Two of these values are also exposed as dictionaries. Two of these values are also exposed as dictionaries.

View File

@ -346,3 +346,10 @@ class Interop(IntEnum):
RelatedImageFileFormat = 4096 RelatedImageFileFormat = 4096
RelatedImageWidth = 4097 RelatedImageWidth = 4097
RleatedImageHeight = 4098 RleatedImageHeight = 4098
class IFD(IntEnum):
Exif = 34665
GPSInfo = 34853
Makernote = 37500
Interop = 40965

View File

@ -47,7 +47,14 @@ except ImportError:
# VERSION was removed in Pillow 6.0.0. # VERSION was removed in Pillow 6.0.0.
# PILLOW_VERSION was removed in Pillow 9.0.0. # PILLOW_VERSION was removed in Pillow 9.0.0.
# Use __version__ instead. # Use __version__ instead.
from . import ImageMode, TiffTags, UnidentifiedImageError, __version__, _plugins from . import (
ExifTags,
ImageMode,
TiffTags,
UnidentifiedImageError,
__version__,
_plugins,
)
from ._binary import i32le, o32be, o32le from ._binary import i32le, o32be, o32le
from ._deprecate import deprecate from ._deprecate import deprecate
from ._util import DeferredError, is_path from ._util import DeferredError, is_path
@ -3598,14 +3605,16 @@ class Exif(MutableMapping):
merged_dict = dict(self) merged_dict = dict(self)
# get EXIF extension # get EXIF extension
if 0x8769 in self: if ExifTags.IFD.Exif in self:
ifd = self._get_ifd_dict(self[0x8769]) ifd = self._get_ifd_dict(self[ExifTags.IFD.Exif])
if ifd: if ifd:
merged_dict.update(ifd) merged_dict.update(ifd)
# GPS # GPS
if 0x8825 in self: if ExifTags.IFD.GPSInfo in self:
merged_dict[0x8825] = self._get_ifd_dict(self[0x8825]) merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict(
self[ExifTags.IFD.GPSInfo]
)
return merged_dict return merged_dict
@ -3615,30 +3624,34 @@ class Exif(MutableMapping):
head = self._get_head() head = self._get_head()
ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head)
for tag, value in self.items(): for tag, value in self.items():
if tag in [0x8769, 0x8225, 0x8825] and not isinstance(value, dict): if tag in [
ExifTags.IFD.Exif,
0x8225,
ExifTags.IFD.GPSInfo,
] and not isinstance(value, dict):
value = self.get_ifd(tag) value = self.get_ifd(tag)
if ( if (
tag == 0x8769 tag == ExifTags.IFD.Exif
and 0xA005 in value and ExifTags.IFD.Interop in value
and not isinstance(value[0xA005], dict) and not isinstance(value[ExifTags.IFD.Interop], dict)
): ):
value = value.copy() value = value.copy()
value[0xA005] = self.get_ifd(0xA005) value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop)
ifd[tag] = value ifd[tag] = value
return b"Exif\x00\x00" + head + ifd.tobytes(offset) return b"Exif\x00\x00" + head + ifd.tobytes(offset)
def get_ifd(self, tag): def get_ifd(self, tag):
if tag not in self._ifds: if tag not in self._ifds:
if tag in [0x8769, 0x8825]: if tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]:
# exif, gpsinfo # exif, gpsinfo
if tag in self: if tag in self:
self._ifds[tag] = self._get_ifd_dict(self[tag]) self._ifds[tag] = self._get_ifd_dict(self[tag])
elif tag in [0xA005, 0x927C]: elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.Makernote]:
# interop, makernote # interop, makernote
if 0x8769 not in self._ifds: if ExifTags.IFD.Exif not in self._ifds:
self.get_ifd(0x8769) self.get_ifd(ExifTags.IFD.Exif)
tag_data = self._ifds[0x8769][tag] tag_data = self._ifds[ExifTags.IFD.Exif][tag]
if tag == 0x927C: if tag == ExifTags.IFD.Makernote:
# makernote # makernote
from .TiffImagePlugin import ImageFileDirectory_v2 from .TiffImagePlugin import ImageFileDirectory_v2

View File

@ -22,7 +22,14 @@ import itertools
import os import os
import struct import struct
from . import Image, ImageFile, ImageSequence, JpegImagePlugin, TiffImagePlugin from . import (
ExifTags,
Image,
ImageFile,
ImageSequence,
JpegImagePlugin,
TiffImagePlugin,
)
from ._binary import i16be as i16 from ._binary import i16be as i16
from ._binary import o32le from ._binary import o32le
@ -137,7 +144,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"] mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"]
if mptype.startswith("Large Thumbnail"): if mptype.startswith("Large Thumbnail"):
exif = self.getexif().get_ifd(0x8769) exif = self.getexif().get_ifd(ExifTags.IFD.Exif)
if 40962 in exif and 40963 in exif: if 40962 in exif and 40963 in exif:
self._size = (exif[40962], exif[40963]) self._size = (exif[40962], exif[40963])
elif "exif" in self.info: elif "exif" in self.info: