pirate486743186: hmmm.... Maybe add multi-threading support?
The function could take a third parameter, the maximum number of threads to be used, default to one. 

If no time for this, then you could just silently add the third parameter anyway, so that future code is backwards compatible with the first version of the function.
radarhere: While we are concerned with backwards compatibility, I don't think that we are concerned with forwards compatibility.

Nothing else in the Pillow runtime uses multiprocessing, so I'm not personally inclined to integrate it here. If anyone else feels otherwise, feel free to comment. Multiprocessing can't be applied to the process of splitting up a single image into frames, because it uses the same file pointer, but it could be applied to the supplied function. If a user wanted to do that, they could just -

```python
from PIL import Image, ImageSequence
im = Image.open('Tests/images/iss634.gif')

ims = ImageSequence.all_frames(im)

from multiprocessing import Pool
def f(im_frame):
    return im_frame.rotate(180)
ims = Pool(5).map(f, ims)

ims[0].save('out.gif', save_all=True, append_images=ims[1:])
```
pirate486743186: but isn't this a special case? You are basically processing multiple images at once. And it seams it would be used frequently IMHO.
diff --git a/docs/releasenotes/6.1.0.rst b/docs/releasenotes/6.1.0.rst
index 98568fb52..851dcb2d0 100644
--- a/docs/releasenotes/6.1.0.rst
+++ b/docs/releasenotes/6.1.0.rst
@@ -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
 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
 ^^^^^^^^^^^^^^^
 
diff --git a/src/PIL/ImageSequence.py b/src/PIL/ImageSequence.py
index 84199fe27..f9be92d48 100644
--- a/src/PIL/ImageSequence.py
+++ b/src/PIL/ImageSequence.py
@@ -54,3 +54,25 @@ class Iterator(object):
 
     def next(self):
         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

Transforms and enhancements across all frames
It would be nice if transforms and enhancements could be applied on animations.
diff --git a/Tests/test_imagesequence.py b/Tests/test_imagesequence.py
index 38645f133..5d90dc4c5 100644
--- a/Tests/test_imagesequence.py
+++ b/Tests/test_imagesequence.py
@@ -74,3 +74,25 @@ class TestImageSequence(PillowTestCase):
         im.seek(0)
         color2 = im.getpalette()[0:3]
         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)

pip install -e .[dev]
parse_log_pytest
requirements.txt
apt-get update apt-get install -y gcc libjpeg-dev zlib1g-dev libtiff5-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev libharfbuzz-dev libfribidi-dev libxcb1-dev
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.16
babel==2.17.0
black==25.1.0
blessed==1.20.0
build==1.2.2.post1
certifi==2025.1.31
charset-normalizer==3.4.1
check-manifest==0.50
click==8.1.8
cov-core==1.15.0
coverage==7.8.0
coveralls==4.0.1
docopt==0.6.2
docutils==0.21.2
exceptiongroup==1.2.2
idna==3.10
imagesize==1.4.1
importlib_metadata==8.6.1
iniconfig==2.1.0
jarn.viewdoc==2.7
Jinja2==3.1.6
MarkupSafe==3.0.2
mypy-extensions==1.0.0
olefile==0.47
packaging==24.2
pathspec==0.12.1
-e git+https://github.com/python-pillow/Pillow.git@32d10505a30207a81bb9536d46bd12ec1e7b191f#egg=Pillow
platformdirs==4.3.7
pluggy==1.5.0
pycodestyle==2.13.0
pyflakes==3.3.1
Pygments==2.19.1
pyproject_hooks==1.2.0
pyroma==4.2
pytest==8.3.5
pytest-cov==6.0.0
pytz==2025.2
requests==2.32.3
six==1.17.0
snowballstemmer==2.2.0
Sphinx==7.4.7
sphinx-rtd-theme==3.0.2
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
tomli==2.2.1
trove-classifiers==2025.3.19.19
typing_extensions==4.13.0
urllib3==2.3.0
wcwidth==0.2.13
zipp==3.21.0

name: Pillow
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.16
      - babel==2.17.0
      - black==25.1.0
      - blessed==1.20.0
      - build==1.2.2.post1
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - check-manifest==0.50
      - click==8.1.8
      - cov-core==1.15.0
      - coverage==7.8.0
      - coveralls==4.0.1
      - docopt==0.6.2
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jarn-viewdoc==2.7
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - mypy-extensions==1.0.0
      - olefile==0.47
      - packaging==24.2
      - pathspec==0.12.1
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pygments==2.19.1
      - pyproject-hooks==1.2.0
      - pyroma==4.2
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - pytz==2025.2
      - requests==2.32.3
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==7.4.7
      - sphinx-rtd-theme==3.0.2
      - sphinxcontrib-applehelp==2.0.0
      - sphinxcontrib-devhelp==2.0.0
      - sphinxcontrib-htmlhelp==2.1.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==2.0.0
      - sphinxcontrib-serializinghtml==2.0.0
      - tomli==2.2.1
      - trove-classifiers==2025.3.19.19
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - wcwidth==0.2.13
      - zipp==3.21.0
prefix: /opt/conda/envs/Pillow

Tests/test_imagesequence.py::TestImageSequence::test_all_frames
Tests/test_imagesequence.py::TestImageSequence::test_consecutive Tests/test_imagesequence.py::TestImageSequence::test_iterator Tests/test_imagesequence.py::TestImageSequence::test_iterator_min_frame Tests/test_imagesequence.py::TestImageSequence::test_libtiff Tests/test_imagesequence.py::TestImageSequence::test_palette_mmap Tests/test_imagesequence.py::TestImageSequence::test_sanity Tests/test_imagesequence.py::TestImageSequence::test_tiff
src/PIL/ImageSequence.py docs/releasenotes/6.1.0.rst
src/PIL/ImageSequence.py docs/releasenotes/6.1.0.rst