diff --git a/Tests/images/xmp_test.jpg b/Tests/images/xmp_test.jpg new file mode 100644 index 000000000..4b9354f3a Binary files /dev/null and b/Tests/images/xmp_test.jpg differ diff --git a/Tests/test_image_getxmp.py b/Tests/test_image_getxmp.py new file mode 100644 index 000000000..a684d6f0c --- /dev/null +++ b/Tests/test_image_getxmp.py @@ -0,0 +1,9 @@ +from PIL import Image + + +def test_getxmp(): + with Image.open("Tests/images/xmp_test.jpg") as im: + xmp = im.getxmp() + + assert isinstance(xmp, dict) + assert xmp["Description"]["Version"] == "10.4" diff --git a/src/PIL/Image.py b/src/PIL/Image.py index ebeaf3c74..062fa9280 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -528,6 +528,7 @@ class Image: self.readonly = 0 self.pyaccess = None self._exif = None + self._xmp = None def __getattr__(self, name): if name == "category": @@ -1339,6 +1340,27 @@ class Image: return self._exif + def getxmp(self): + """ + Returns a dictionary containing the xmp tags for a given image. + :returns: XMP tags in a dictionary. + """ + + if self._xmp is None: + self._xmp = {} + + for segment, content in self.applist: + if segment == "APP1": + marker, xmp_tags = content.rsplit(b"\x00", 1) + if marker == b"http://ns.adobe.com/xap/1.0/": + root = xml.etree.ElementTree.fromstring(xmp_tags) + for element in root.findall(".//"): + self._xmp[element.tag.split("}")[1]] = { + child.split("}")[1]: value + for child, value in element.attrib.items() + } + return self._xmp + def getim(self): """ Returns a capsule that points to the internal image memory.