mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
Merge pull request #3674 from radarhere/png_exif
Added EXIF support for PNG
This commit is contained in:
commit
25e40dd978
BIN
Tests/images/exif.png
Normal file
BIN
Tests/images/exif.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 175 KiB |
|
@ -590,6 +590,40 @@ class TestFilePng(PillowTestCase):
|
||||||
im = Image.open("Tests/images/hopper_idat_after_image_end.png")
|
im = Image.open("Tests/images/hopper_idat_after_image_end.png")
|
||||||
self.assertEqual(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
self.assertEqual(im.text, {'TXT': 'VALUE', 'ZIP': 'VALUE'})
|
||||||
|
|
||||||
|
def test_exif(self):
|
||||||
|
im = Image.open("Tests/images/exif.png")
|
||||||
|
exif = im._getexif()
|
||||||
|
self.assertEqual(exif[274], 1)
|
||||||
|
|
||||||
|
def test_exif_save(self):
|
||||||
|
im = Image.open("Tests/images/exif.png")
|
||||||
|
|
||||||
|
test_file = self.tempfile("temp.png")
|
||||||
|
im.save(test_file)
|
||||||
|
|
||||||
|
reloaded = Image.open(test_file)
|
||||||
|
exif = reloaded._getexif()
|
||||||
|
self.assertEqual(exif[274], 1)
|
||||||
|
|
||||||
|
def test_exif_from_jpg(self):
|
||||||
|
im = Image.open("Tests/images/pil_sample_rgb.jpg")
|
||||||
|
|
||||||
|
test_file = self.tempfile("temp.png")
|
||||||
|
im.save(test_file)
|
||||||
|
|
||||||
|
reloaded = Image.open(test_file)
|
||||||
|
exif = reloaded._getexif()
|
||||||
|
self.assertEqual(exif[305], "Adobe Photoshop CS Macintosh")
|
||||||
|
|
||||||
|
def test_exif_argument(self):
|
||||||
|
im = Image.open(TEST_PNG_FILE)
|
||||||
|
|
||||||
|
test_file = self.tempfile("temp.png")
|
||||||
|
im.save(test_file, exif=b"exifstring")
|
||||||
|
|
||||||
|
reloaded = Image.open(test_file)
|
||||||
|
self.assertEqual(reloaded.info["exif"], b"Exif\x00\x00exifstring")
|
||||||
|
|
||||||
@unittest.skipUnless(HAVE_WEBP and _webp.HAVE_WEBPANIM,
|
@unittest.skipUnless(HAVE_WEBP and _webp.HAVE_WEBPANIM,
|
||||||
"WebP support not installed with animation")
|
"WebP support not installed with animation")
|
||||||
def test_apng(self):
|
def test_apng(self):
|
||||||
|
|
|
@ -462,6 +462,10 @@ PNG
|
||||||
Pillow identifies, reads, and writes PNG files containing ``1``, ``L``, ``P``,
|
Pillow identifies, reads, and writes PNG files containing ``1``, ``L``, ``P``,
|
||||||
``RGB``, or ``RGBA`` data. Interlaced files are supported as of v1.1.7.
|
``RGB``, or ``RGBA`` data. Interlaced files are supported as of v1.1.7.
|
||||||
|
|
||||||
|
As of Pillow 6.0, EXIF data can be read from PNG images. However, unlike other
|
||||||
|
image formats, EXIF data is not guaranteed to have been read until
|
||||||
|
:py:meth:`~PIL.Image.Image.load` has been called.
|
||||||
|
|
||||||
The :py:meth:`~PIL.Image.Image.open` method sets the following
|
The :py:meth:`~PIL.Image.Image.open` method sets the following
|
||||||
:py:attr:`~PIL.Image.Image.info` properties, when appropriate:
|
:py:attr:`~PIL.Image.Image.info` properties, when appropriate:
|
||||||
|
|
||||||
|
@ -527,6 +531,11 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
||||||
**icc_profile**
|
**icc_profile**
|
||||||
The ICC Profile to include in the saved file.
|
The ICC Profile to include in the saved file.
|
||||||
|
|
||||||
|
**exif**
|
||||||
|
The exif data to include in the saved file.
|
||||||
|
|
||||||
|
.. versionadded:: 6.0.0
|
||||||
|
|
||||||
**bits (experimental)**
|
**bits (experimental)**
|
||||||
For ``P`` images, this option controls how many bits to store. If omitted,
|
For ``P`` images, this option controls how many bits to store. If omitted,
|
||||||
the PNG writer uses 8 bits (256 colors).
|
the PNG writer uses 8 bits (256 colors).
|
||||||
|
|
|
@ -112,6 +112,13 @@ Image.quantize
|
||||||
|
|
||||||
The `dither` option is now a customisable parameter (was previously hardcoded to `1`). This parameter takes the same values used in `Image.convert`
|
The `dither` option is now a customisable parameter (was previously hardcoded to `1`). This parameter takes the same values used in `Image.convert`
|
||||||
|
|
||||||
|
PNG EXIF Data
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
EXIF data can now be read from and saved to PNG images. However, unlike other image
|
||||||
|
formats, EXIF data is not guaranteed to have been read until
|
||||||
|
:py:meth:`~PIL.Image.Image.load` has been called.
|
||||||
|
|
||||||
Other Changes
|
Other Changes
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
|
@ -529,6 +529,11 @@ class PngStream(ChunkStream):
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def chunk_eXIf(self, pos, length):
|
||||||
|
s = ImageFile._safe_read(self.fp, length)
|
||||||
|
self.im_info["exif"] = b"Exif\x00\x00"+s
|
||||||
|
return s
|
||||||
|
|
||||||
# APNG chunks
|
# APNG chunks
|
||||||
def chunk_acTL(self, pos, length):
|
def chunk_acTL(self, pos, length):
|
||||||
s = ImageFile._safe_read(self.fp, length)
|
s = ImageFile._safe_read(self.fp, length)
|
||||||
|
@ -683,6 +688,12 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
self.png.close()
|
self.png.close()
|
||||||
self.png = None
|
self.png = None
|
||||||
|
|
||||||
|
def _getexif(self):
|
||||||
|
if "exif" not in self.info:
|
||||||
|
self.load()
|
||||||
|
from .JpegImagePlugin import _getexif
|
||||||
|
return _getexif(self)
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# PNG writer
|
# PNG writer
|
||||||
|
@ -861,6 +872,12 @@ def _save(im, fp, filename, chunk=putchunk):
|
||||||
chunks.remove(cid)
|
chunks.remove(cid)
|
||||||
chunk(fp, cid, data)
|
chunk(fp, cid, data)
|
||||||
|
|
||||||
|
exif = im.encoderinfo.get("exif", im.info.get("exif"))
|
||||||
|
if exif:
|
||||||
|
if exif.startswith(b"Exif\x00\x00"):
|
||||||
|
exif = exif[6:]
|
||||||
|
chunk(fp, b"eXIf", exif)
|
||||||
|
|
||||||
ImageFile._save(im, _idat(fp, chunk),
|
ImageFile._save(im, _idat(fp, chunk),
|
||||||
[("zip", (0, 0)+im.size, 0, rawmode)])
|
[("zip", (0, 0)+im.size, 0, rawmode)])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user