ImageSequence.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. from __future__ import annotations
  17. from typing import Callable
  18. from . import Image
  19. class Iterator:
  20. """
  21. This class implements an iterator object that can be used to loop
  22. over an image sequence.
  23. You can use the ``[]`` operator to access elements by index. This operator
  24. will raise an :py:exc:`IndexError` if you try to access a nonexistent
  25. frame.
  26. :param im: An image object.
  27. """
  28. def __init__(self, im: Image.Image):
  29. if not hasattr(im, "seek"):
  30. msg = "im must have seek method"
  31. raise AttributeError(msg)
  32. self.im = im
  33. self.position = getattr(self.im, "_min_frame", 0)
  34. def __getitem__(self, ix: int) -> Image.Image:
  35. try:
  36. self.im.seek(ix)
  37. return self.im
  38. except EOFError as e:
  39. msg = "end of sequence"
  40. raise IndexError(msg) from e
  41. def __iter__(self) -> Iterator:
  42. return self
  43. def __next__(self) -> Image.Image:
  44. try:
  45. self.im.seek(self.position)
  46. self.position += 1
  47. return self.im
  48. except EOFError as e:
  49. msg = "end of sequence"
  50. raise StopIteration(msg) from e
  51. def all_frames(
  52. im: Image.Image | list[Image.Image],
  53. func: Callable[[Image.Image], Image.Image] | None = None,
  54. ) -> list[Image.Image]:
  55. """
  56. Applies a given function to all frames in an image or a list of images.
  57. The frames are returned as a list of separate images.
  58. :param im: An image, or a list of images.
  59. :param func: The function to apply to all of the image frames.
  60. :returns: A list of images.
  61. """
  62. if not isinstance(im, list):
  63. im = [im]
  64. ims = []
  65. for imSequence in im:
  66. current = imSequence.tell()
  67. ims += [im_frame.copy() for im_frame in Iterator(imSequence)]
  68. imSequence.seek(current)
  69. return [func(im) for im in ims] if func else ims