Skip to content

Commit

Permalink
Adjust is_animated behavior
Browse files Browse the repository at this point in the history
- Make is_animated APNG behavior consistent with other Pillow formats
- is_animated will be true when n_frames is greater than 1 (for APNG
  this depends on animation frame count + presence or absence of a
  default image)
  • Loading branch information
pmrowla authored and radarhere committed Feb 15, 2020
1 parent fba45e9 commit b20544a
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 5 deletions.
8 changes: 6 additions & 2 deletions Tests/test_file_apng.py
Expand Up @@ -12,14 +12,16 @@ class TestFilePng(PillowTestCase):
# (referenced from https://wiki.mozilla.org/APNG_Specification)
def test_apng_basic(self):
with Image.open("Tests/images/apng/single_frame.png") as im:
self.assertTrue(im.is_animated)
self.assertFalse(im.is_animated)
self.assertEqual(im.n_frames, 1)
self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertIsNone(im.info.get("default_image"))
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
self.assertEqual(im.getpixel((64, 32)), (0, 255, 0, 255))

with Image.open("Tests/images/apng/single_frame_default.png") as im:
self.assertTrue(im.is_animated)
self.assertEqual(im.n_frames, 2)
self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertTrue(im.info.get("default_image"))
self.assertEqual(im.getpixel((0, 0)), (255, 0, 0, 255))
Expand Down Expand Up @@ -311,7 +313,8 @@ def test_apng_save(self):

with Image.open(test_file) as im:
im.load()
self.assertTrue(im.is_animated)
self.assertFalse(im.is_animated)
self.assertEqual(im.n_frames, 1)
self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertIsNone(im.info.get("default_image"))
self.assertEqual(im.getpixel((0, 0)), (0, 255, 0, 255))
Expand All @@ -328,6 +331,7 @@ def test_apng_save(self):
with Image.open(test_file) as im:
im.load()
self.assertTrue(im.is_animated)
self.assertEqual(im.n_frames, 2)
self.assertEqual(im.get_format_mimetype(), "image/apng")
self.assertTrue(im.info.get("default_image"))
im.seek(1)
Expand Down
7 changes: 5 additions & 2 deletions docs/handbook/image-file-formats.rst
Expand Up @@ -559,8 +559,11 @@ APNG sequences
The PNG loader includes limited support for reading and writing Animated Portable
Network Graphics (APNG) files.
When an APNG file is loaded, :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype`
will return ``"image/apng"``, and the :py:attr:`~PIL.Image.Image.is_animated` property
will be ``True`` (even for single frame APNG files).
will return ``"image/apng"``. The value of the :py:attr:`~PIL.Image.Image.is_animated`
property will be ``True`` when the :py:attr:`~PIL.Image.Image.n_frames` property is
greater than 1. For APNG files, the ``n_frames`` property depends on both the animation
frame count as well as the presence or absence of a default image. See the
``default_image`` property documentation below for more details.
The :py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods
are supported.

Expand Down
2 changes: 1 addition & 1 deletion src/PIL/PngImagePlugin.py
Expand Up @@ -717,7 +717,7 @@ def n_frames(self):

@property
def is_animated(self):
return self._n_frames is not None
return self._n_frames is not None and self._n_frames > 1

def verify(self):
"""Verify PNG file"""
Expand Down

0 comments on commit b20544a

Please sign in to comment.