ImageSequence.py 2.2 KB

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