mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-11-14 05:36:48 +03:00
Added getxmp() for TIFF
This commit is contained in:
parent
c1fbe2d975
commit
ae3bdf87f0
|
@ -600,6 +600,16 @@ class TestFileTiff:
|
||||||
with Image.open(outfile) as reloaded:
|
with Image.open(outfile) as reloaded:
|
||||||
assert "icc_profile" not in reloaded.info
|
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):
|
def test_close_on_load_exclusive(self, tmp_path):
|
||||||
# similar to test_fd_leak, but runs on unixlike os
|
# similar to test_fd_leak, but runs on unixlike os
|
||||||
tmpfile = str(tmp_path / "temp.tif")
|
tmpfile = str(tmp_path / "temp.tif")
|
||||||
|
|
|
@ -31,6 +31,7 @@ import io
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
import xml.etree.ElementTree
|
||||||
|
|
||||||
from . import Image
|
from . import Image
|
||||||
from ._util import isPath
|
from ._util import isPath
|
||||||
|
@ -309,6 +310,30 @@ class ImageFile(Image.Image):
|
||||||
|
|
||||||
return self.tell() != frame
|
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):
|
class StubImageFile(ImageFile):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -40,7 +40,6 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.ElementTree
|
|
||||||
|
|
||||||
from . import Image, ImageFile, TiffImagePlugin
|
from . import Image, ImageFile, TiffImagePlugin
|
||||||
from ._binary import i16be as i16
|
from ._binary import i16be as i16
|
||||||
|
@ -492,29 +491,7 @@ class JpegImageFile(ImageFile.ImageFile):
|
||||||
if segment == "APP1":
|
if segment == "APP1":
|
||||||
marker, xmp_tags = content.rsplit(b"\x00", 1)
|
marker, xmp_tags = content.rsplit(b"\x00", 1)
|
||||||
if marker == b"http://ns.adobe.com/xap/1.0/":
|
if marker == b"http://ns.adobe.com/xap/1.0/":
|
||||||
|
self._getxmp(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)
|
|
||||||
return self._xmp
|
return self._xmp
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1032,6 +1032,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
self.__fp = self.fp
|
self.__fp = self.fp
|
||||||
self._frame_pos = []
|
self._frame_pos = []
|
||||||
self._n_frames = None
|
self._n_frames = None
|
||||||
|
self._xmp = None
|
||||||
|
|
||||||
logger.debug("*** TiffImageFile._open ***")
|
logger.debug("*** TiffImageFile._open ***")
|
||||||
logger.debug(f"- __first: {self.__first}")
|
logger.debug(f"- __first: {self.__first}")
|
||||||
|
@ -1101,6 +1102,19 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
"""Return the current frame number"""
|
"""Return the current frame number"""
|
||||||
return self.__frame
|
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):
|
def load(self):
|
||||||
if self.tile and self.use_load_libtiff:
|
if self.tile and self.use_load_libtiff:
|
||||||
return self._load_libtiff()
|
return self._load_libtiff()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user