Merge pull request #3778 from radarhere/all_frames

Added ImageSequence all_frames
This commit is contained in:
Andrew Murray 2019-06-30 07:55:34 +10:00 committed by GitHub
commit 9074eda608
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 0 deletions

View File

@ -74,3 +74,25 @@ class TestImageSequence(PillowTestCase):
im.seek(0) im.seek(0)
color2 = im.getpalette()[0:3] color2 = im.getpalette()[0:3]
self.assertEqual(color1, color2) self.assertEqual(color1, color2)
def test_all_frames(self):
# Test a single image
im = Image.open("Tests/images/iss634.gif")
ims = ImageSequence.all_frames(im)
self.assertEqual(len(ims), 42)
for i, im_frame in enumerate(ims):
self.assertFalse(im_frame is im)
im.seek(i)
self.assert_image_equal(im, im_frame)
# Test a series of images
ims = ImageSequence.all_frames([im, hopper(), im])
self.assertEqual(len(ims), 85)
# Test an operation
ims = ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(90))
for i, im_frame in enumerate(ims):
im.seek(i)
self.assert_image_equal(im.rotate(90), im_frame)

View File

@ -11,6 +11,14 @@ An optional ``include_layered_windows`` parameter has been added to ``ImageGrab.
defaulting to ``False``. If true, layered windows will be included in the resulting defaulting to ``False``. If true, layered windows will be included in the resulting
image on Windows. image on Windows.
ImageSequence.all_frames
^^^^^^^^^^^^^^^^^^^^^^^^
A new method to facilitate applying a given function to all frames in an image, or to
all frames in a list of images. The frames are returned as a list of separate images.
For example, ``ImageSequence.all_frames(im, lambda im_frame: im_frame.rotate(90))``
could be used to return all frames from an image, each rotated 90 degrees.
Variation fonts Variation fonts
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^

View File

@ -54,3 +54,25 @@ class Iterator(object):
def next(self): def next(self):
return self.__next__() return self.__next__()
def all_frames(im, func=None):
"""
Applies a given function to all frames in an image or a list of images.
The frames are returned as a list of separate images.
:param im: An image, or a list of images.
:param func: The function to apply to all of the image frames.
:returns: A list of images.
"""
if not isinstance(im, list):
im = [im]
ims = []
for imSequence in im:
current = imSequence.tell()
ims += [im_frame.copy() for im_frame in Iterator(imSequence)]
imSequence.seek(current)
return [func(im) for im in ims] if func else ims