mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-14 03:21:44 +03:00
Allow ImageMagick zTXt chunks to be extracted after copy()
This commit is contained in:
parent
1e63f772f8
commit
f21816918e
|
@ -591,19 +591,23 @@ class TestFilePng:
|
||||||
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
||||||
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
def test_exif(self):
|
||||||
"test_file",
|
# With an EXIF chunk
|
||||||
[
|
with Image.open("Tests/images/exif.png") as im:
|
||||||
"Tests/images/exif.png", # With an EXIF chunk
|
|
||||||
"Tests/images/exif_imagemagick.png", # With an ImageMagick zTXt chunk
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_exif(self, test_file):
|
|
||||||
with Image.open(test_file) as im:
|
|
||||||
exif = im._getexif()
|
exif = im._getexif()
|
||||||
assert exif[274] == 1
|
assert exif[274] == 1
|
||||||
|
|
||||||
def test_xmp_tags_orientation(self):
|
# With an ImageMagick zTXt chunk
|
||||||
|
with Image.open("Tests/images/exif_imagemagick.png") as im:
|
||||||
|
exif = im._getexif()
|
||||||
|
assert exif[274] == 1
|
||||||
|
|
||||||
|
# Assert that info still can be extracted
|
||||||
|
# when the image is no longer a PngImageFile instance
|
||||||
|
exif = im.copy().getexif()
|
||||||
|
assert exif[274] == 1
|
||||||
|
|
||||||
|
# With XMP tags
|
||||||
with Image.open("Tests/images/xmp_tags_orientation.png") as im:
|
with Image.open("Tests/images/xmp_tags_orientation.png") as im:
|
||||||
exif = im.getexif()
|
exif = im.getexif()
|
||||||
assert exif[274] == 3
|
assert exif[274] == 3
|
||||||
|
|
|
@ -1298,30 +1298,31 @@ class Image:
|
||||||
return tuple(extrema)
|
return tuple(extrema)
|
||||||
return self.im.getextrema()
|
return self.im.getextrema()
|
||||||
|
|
||||||
def _parse_xmp_tags(self):
|
|
||||||
if 0x0112 in self._exif:
|
|
||||||
return
|
|
||||||
|
|
||||||
xmp_tags = self.info.get("XML:com.adobe.xmp")
|
|
||||||
if not xmp_tags:
|
|
||||||
return
|
|
||||||
|
|
||||||
root = xml.etree.ElementTree.fromstring(xmp_tags)
|
|
||||||
for elem in root.iter():
|
|
||||||
if elem.tag.endswith("}Description"):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
orientation = elem.attrib.get("{http://ns.adobe.com/tiff/1.0/}Orientation")
|
|
||||||
if orientation:
|
|
||||||
self._exif[0x0112] = int(orientation)
|
|
||||||
|
|
||||||
def getexif(self):
|
def getexif(self):
|
||||||
if self._exif is None:
|
if self._exif is None:
|
||||||
self._exif = Exif()
|
self._exif = Exif()
|
||||||
self._exif.load(self.info.get("exif"))
|
|
||||||
self._parse_xmp_tags()
|
exif_info = self.info.get("exif")
|
||||||
|
if exif_info is None and "Raw profile type exif" in self.info:
|
||||||
|
exif_info = bytes.fromhex(
|
||||||
|
"".join(self.info["Raw profile type exif"].split("\n")[3:])
|
||||||
|
)
|
||||||
|
self._exif.load(exif_info)
|
||||||
|
|
||||||
|
# XMP tags
|
||||||
|
if 0x0112 not in self._exif:
|
||||||
|
xmp_tags = self.info.get("XML:com.adobe.xmp")
|
||||||
|
if xmp_tags:
|
||||||
|
root = xml.etree.ElementTree.fromstring(xmp_tags)
|
||||||
|
for elem in root.iter():
|
||||||
|
if elem.tag.endswith("}Description"):
|
||||||
|
orientation = elem.attrib.get(
|
||||||
|
"{http://ns.adobe.com/tiff/1.0/}Orientation"
|
||||||
|
)
|
||||||
|
if orientation:
|
||||||
|
self._exif[0x0112] = int(orientation)
|
||||||
|
break
|
||||||
|
|
||||||
return self._exif
|
return self._exif
|
||||||
|
|
||||||
def getim(self):
|
def getim(self):
|
||||||
|
|
|
@ -931,17 +931,7 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
if "exif" not in self.info:
|
if "exif" not in self.info:
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
if self._exif is None:
|
return super().getexif()
|
||||||
self._exif = Image.Exif()
|
|
||||||
|
|
||||||
exif_info = self.info.get("exif")
|
|
||||||
if exif_info is None and "Raw profile type exif" in self.info:
|
|
||||||
exif_info = bytes.fromhex(
|
|
||||||
"".join(self.info["Raw profile type exif"].split("\n")[3:])
|
|
||||||
)
|
|
||||||
self._exif.load(exif_info)
|
|
||||||
self._parse_xmp_tags()
|
|
||||||
return self._exif
|
|
||||||
|
|
||||||
def _close__fp(self):
|
def _close__fp(self):
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user