Added getxmp() for TIFF

This commit is contained in:
Andrew Murray 2021-06-12 12:17:38 +10:00
parent c1fbe2d975
commit ae3bdf87f0
4 changed files with 50 additions and 24 deletions

View File

@ -600,6 +600,16 @@ class TestFileTiff:
with Image.open(outfile) as reloaded:
assert "icc_profile" not in reloaded.info
def test_xmp(self):
with Image.open("Tests/images/lab.tif") as im:
xmp = im.getxmp()
assert isinstance(xmp, dict)
description = xmp["xmpmeta"]["RDF"]["Description"]
assert description[0]["format"] == "image/tiff"
assert description[3]["BitsPerSample"]["Seq"]["li"] == ["8", "8", "8"]
def test_close_on_load_exclusive(self, tmp_path):
# similar to test_fd_leak, but runs on unixlike os
tmpfile = str(tmp_path / "temp.tif")

View File

@ -31,6 +31,7 @@ import io
import struct
import sys
import warnings
import xml.etree.ElementTree
from . import Image
from ._util import isPath
@ -309,6 +310,30 @@ class ImageFile(Image.Image):
return self.tell() != frame
def _getxmp(self, xmp_tags):
def get_name(tag):
return tag.split("}")[1]
def get_value(element):
children = list(element)
if children:
value = {get_name(k): v for k, v in element.attrib.items()}
for child in children:
name = get_name(child.tag)
child_value = get_value(child)
if name in value:
if not isinstance(value[name], list):
value[name] = [value[name]]
value[name].append(child_value)
else:
value[name] = child_value
return value
else:
return element.text
root = xml.etree.ElementTree.fromstring(xmp_tags)
self._xmp[get_name(root.tag)] = get_value(root)
class StubImageFile(ImageFile):
"""

View File

@ -40,7 +40,6 @@ import subprocess
import sys
import tempfile
import warnings
import xml.etree.ElementTree
from . import Image, ImageFile, TiffImagePlugin
from ._binary import i16be as i16
@ -492,29 +491,7 @@ class JpegImageFile(ImageFile.ImageFile):
if segment == "APP1":
marker, xmp_tags = content.rsplit(b"\x00", 1)
if marker == b"http://ns.adobe.com/xap/1.0/":
def get_name(tag):
return tag.split("}")[1]
def get_value(element):
children = list(element)
if children:
value = {get_name(k): v for k, v in element.attrib.items()}
for child in children:
name = get_name(child.tag)
child_value = get_value(child)
if name in value:
if not isinstance(value[name], list):
value[name] = [value[name]]
value[name].append(child_value)
else:
value[name] = child_value
return value
else:
return element.text
root = xml.etree.ElementTree.fromstring(xmp_tags)
self._xmp[get_name(root.tag)] = get_value(root)
self._getxmp(xmp_tags)
return self._xmp

View File

@ -1032,6 +1032,7 @@ class TiffImageFile(ImageFile.ImageFile):
self.__fp = self.fp
self._frame_pos = []
self._n_frames = None
self._xmp = None
logger.debug("*** TiffImageFile._open ***")
logger.debug(f"- __first: {self.__first}")
@ -1101,6 +1102,19 @@ class TiffImageFile(ImageFile.ImageFile):
"""Return the current frame number"""
return self.__frame
def getxmp(self):
"""
Returns a dictionary containing the XMP tags.
:returns: XMP tags in a dictionary.
"""
if self._xmp is None:
self._xmp = {}
if 700 in self.tag_v2:
self._getxmp(self.tag_v2[700])
return self._xmp
def load(self):
if self.tile and self.use_load_libtiff:
return self._load_libtiff()