mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +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