diff --git a/Tests/images/exif_imagemagick.png b/Tests/images/exif_imagemagick.png new file mode 100644 index 000000000..6f59224c8 Binary files /dev/null and b/Tests/images/exif_imagemagick.png differ diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py index 6789cf66e..345abf11b 100644 --- a/Tests/test_file_png.py +++ b/Tests/test_file_png.py @@ -592,8 +592,15 @@ class TestFilePng: with Image.open("Tests/images/hopper_idat_after_image_end.png") as im: assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"} - def test_exif(self): - with Image.open("Tests/images/exif.png") as im: + @pytest.mark.parametrize( + "test_file", + [ + "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() assert exif[274] == 1 diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index ee1400d67..fe54b969e 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -694,14 +694,24 @@ class PngImageFile(ImageFile.ImageFile): def _getexif(self): if "exif" not in self.info: self.load() - if "exif" not in self.info: + if "exif" not in self.info and "Raw profile type exif" not in self.info: return None return dict(self.getexif()) def getexif(self): if "exif" not in self.info: self.load() - return ImageFile.ImageFile.getexif(self) + + if self._exif is None: + 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) + return self._exif # --------------------------------------------------------------------