1#
2# The Python Imaging Library.
3# $Id$
4#
5# sequence support classes
6#
7# history:
8# 1997-02-20 fl Created
9#
10# Copyright (c) 1997 by Secret Labs AB.
11# Copyright (c) 1997 by Fredrik Lundh.
12#
13# See the README file for information on usage and redistribution.
14#
15
16##
17from __future__ import annotations
18
19from typing import Callable
20
21from . import Image
22
23
24class Iterator:
25 """
26 This class implements an iterator object that can be used to loop
27 over an image sequence.
28
29 You can use the ``[]`` operator to access elements by index. This operator
30 will raise an :py:exc:`IndexError` if you try to access a nonexistent
31 frame.
32
33 :param im: An image object.
34 """
35
36 def __init__(self, im: Image.Image):
37 if not hasattr(im, "seek"):
38 msg = "im must have seek method"
39 raise AttributeError(msg)
40 self.im = im
41 self.position = getattr(self.im, "_min_frame", 0)
42
43 def __getitem__(self, ix: int) -> Image.Image:
44 try:
45 self.im.seek(ix)
46 return self.im
47 except EOFError as e:
48 msg = "end of sequence"
49 raise IndexError(msg) from e
50
51 def __iter__(self) -> Iterator:
52 return self
53
54 def __next__(self) -> Image.Image:
55 try:
56 self.im.seek(self.position)
57 self.position += 1
58 return self.im
59 except EOFError as e:
60 msg = "end of sequence"
61 raise StopIteration(msg) from e
62
63
64def all_frames(
65 im: Image.Image | list[Image.Image],
66 func: Callable[[Image.Image], Image.Image] | None = None,
67) -> list[Image.Image]:
68 """
69 Applies a given function to all frames in an image or a list of images.
70 The frames are returned as a list of separate images.
71
72 :param im: An image, or a list of images.
73 :param func: The function to apply to all of the image frames.
74 :returns: A list of images.
75 """
76 if not isinstance(im, list):
77 im = [im]
78
79 ims = []
80 for imSequence in im:
81 current = imSequence.tell()
82
83 ims += [im_frame.copy() for im_frame in Iterator(imSequence)]
84
85 imSequence.seek(current)
86 return [func(im) for im in ims] if func else ims