Skip to content
Back to top
View this page

# 11.2.1

Warning

The release of Pillow 11.2.0 was halted prematurely, due to hitting PyPI’s project size limit and concern over the size of Pillow wheels containing libavif. The PyPI limit has now been increased and Pillow 11.2.1 has been released instead, without libavif included in the wheels. To avoid confusion, the incomplete 11.2.0 release has been removed from PyPI.

## Security

### Undefined shift when loading compressed DDS images

When loading some compressed DDS formats, an integer was bitshifted by 24 places to generate the 32 bits of the lookup table. This was undefined behaviour, and has been present since Pillow 3.4.0.

## Deprecations

### Image.Image.get_child_images()

Deprecated since version 11.2.1.

`Image.Image.get_child_images()` has been deprecated. and will be removed in Pillow 13 (2026-10-15). It will be moved to `ImageFile.ImageFile.get_child_images()`. The method uses an image’s file pointer, and so child images could only be retrieved from an `PIL.ImageFile.ImageFile` instance.

## API changes

### `append_images` no longer requires `save_all`

Previously, `save_all` was required to in order to use `append_images`. Now, `save_all` will default to `True` if `append_images` is not empty and the format supports saving multiple frames:

    im.save("out.gif", append_images=ims)

## API additions

### `"justify"` multiline text alignment

In addition to `"left"`, `"center"` and `"right"`, multiline text can also be aligned using `"justify"` in `ImageDraw`:

    from PIL import Image, ImageDraw
    im = Image.new("RGB", (50, 25))
    draw = ImageDraw.Draw(im)
    draw.multiline_text((0, 0), "Multiline\ntext 1", align="justify")
    draw.multiline_textbbox((0, 0), "Multiline\ntext 2", align="justify")

### Specify window in ImageGrab on Windows

When using `grab()`, a specific window can be selected using the HWND:

    from PIL import ImageGrab
    ImageGrab.grab(window=hwnd)

### Check for MozJPEG

You can check if Pillow has been built against the MozJPEG version of the libjpeg library, and what version of MozJPEG is being used:

    from PIL import features
    features.check_feature("mozjpeg")  # True or False
    features.version_feature("mozjpeg")  # "4.1.1" for example, or None

### Saving compressed DDS images

Compressed DDS images can now be saved using a `pixel_format` argument. DXT1, DXT3, DXT5, BC2, BC3 and BC5 are supported:

    im.save("out.dds", pixel_format="DXT1")

## Other changes

### Arrow support

Arrow is an in-memory data exchange format that is the spiritual successor to the NumPy array interface. It provides for zero-copy access to columnar data, which in our case is `Image` data.

To create an image with zero-copy shared memory from an object exporting the arrow_c_array interface protocol:

    from PIL import Image
    import pyarrow as pa
    arr = pa.array([0]*(5*5*4), type=pa.uint8())
    im = Image.fromarrow(arr, 'RGBA', (5, 5))

Pillow images can also be converted to Arrow objects:

    from PIL import Image
    import pyarrow as pa
    im = Image.open('hopper.jpg')
    arr = pa.array(im)

### Reading and writing AVIF images

Pillow can now read and write AVIF images when built from source with libavif 1.0.0 or later.