12.0.0
------

Backwards incompatible changes
==============================

Python 3.9
^^^^^^^^^^

Pillow has dropped support for Python 3.9,
which reached end-of-life in October 2025.

ImageFile.raise_oserror
^^^^^^^^^^^^^^^^^^^^^^^

``ImageFile.raise_oserror()`` has been removed. The function was undocumented and was
only useful for translating error codes returned by a codec's ``decode()`` method,
which ImageFile already did automatically.

IptcImageFile helper functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been removed. These were undocumented helper functions
intended for internal use, so there is no replacement. They can each be replaced by a
single line of code using builtin functions in Python.

ImageCms constants and versions() function
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A number of constants and a function in :py:mod:`.ImageCms` have been removed. This
includes a table of flags based on LittleCMS version 1 which has been replaced with a
new class :py:class:`.ImageCms.Flags` based on LittleCMS 2 flags.

============================================  ====================================================
Deprecated                                    Use instead
============================================  ====================================================
``ImageCms.DESCRIPTION``                      No replacement
``ImageCms.VERSION``                          ``PIL.__version__``
``ImageCms.FLAGS["MATRIXINPUT"]``             :py:attr:`.ImageCms.Flags.CLUT_POST_LINEARIZATION`
``ImageCms.FLAGS["MATRIXOUTPUT"]``            :py:attr:`.ImageCms.Flags.FORCE_CLUT`
``ImageCms.FLAGS["MATRIXONLY"]``              No replacement
``ImageCms.FLAGS["NOWHITEONWHITEFIXUP"]``     :py:attr:`.ImageCms.Flags.NOWHITEONWHITEFIXUP`
``ImageCms.FLAGS["NOPRELINEARIZATION"]``      :py:attr:`.ImageCms.Flags.CLUT_PRE_LINEARIZATION`
``ImageCms.FLAGS["GUESSDEVICECLASS"]``        :py:attr:`.ImageCms.Flags.GUESSDEVICECLASS`
``ImageCms.FLAGS["NOTCACHE"]``                :py:attr:`.ImageCms.Flags.NOCACHE`
``ImageCms.FLAGS["NOTPRECALC"]``              :py:attr:`.ImageCms.Flags.NOOPTIMIZE`
``ImageCms.FLAGS["NULLTRANSFORM"]``           :py:attr:`.ImageCms.Flags.NULLTRANSFORM`
``ImageCms.FLAGS["HIGHRESPRECALC"]``          :py:attr:`.ImageCms.Flags.HIGHRESPRECALC`
``ImageCms.FLAGS["LOWRESPRECALC"]``           :py:attr:`.ImageCms.Flags.LOWRESPRECALC`
``ImageCms.FLAGS["GAMUTCHECK"]``              :py:attr:`.ImageCms.Flags.GAMUTCHECK`
``ImageCms.FLAGS["WHITEBLACKCOMPENSATION"]``  :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["BLACKPOINTCOMPENSATION"]``  :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["SOFTPROOFING"]``            :py:attr:`.ImageCms.Flags.SOFTPROOFING`
``ImageCms.FLAGS["PRESERVEBLACK"]``           :py:attr:`.ImageCms.Flags.NONEGATIVES`
``ImageCms.FLAGS["NODEFAULTRESOURCEDEF"]``    :py:attr:`.ImageCms.Flags.NODEFAULTRESOURCEDEF`
``ImageCms.FLAGS["GRIDPOINTS"]``              :py:attr:`.ImageCms.Flags.GRIDPOINTS()`
``ImageCms.versions()``                       :py:func:`PIL.features.version_module` with
                                              ``feature="littlecms2"``, :py:data:`sys.version` or
                                              :py:data:`sys.version_info`, and ``PIL.__version__``
============================================  ====================================================

ImageMath eval()
^^^^^^^^^^^^^^^^

``ImageMath.eval()`` has been removed. Use :py:meth:`~PIL.ImageMath.lambda_eval` or
:py:meth:`~PIL.ImageMath.unsafe_eval` instead.

BGR;15, BGR;16 and BGR;24
^^^^^^^^^^^^^^^^^^^^^^^^^

The experimental BGR;15, BGR;16 and BGR;24 modes have been removed.

Non-image modes in ImageCms
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The use in :py:mod:`.ImageCms` of input modes and output modes that are not Pillow
image modes has been removed. Defaulting to "L" or "1" if the mode cannot be mapped has
also been removed.

Support for LibTIFF earlier than 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Support for LibTIFF earlier than version 4 has been removed.
Upgrade to a newer version of LibTIFF instead.

ImageDraw.getdraw hints parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been removed.

FreeType 2.9.0
^^^^^^^^^^^^^^

Support for FreeType 2.9.0 has been removed. FreeType 2.9.1 is the minimum version
supported.

We recommend upgrading to at least FreeType `2.10.4`_, which fixed a severe
vulnerability introduced in FreeType 2.6 (:cve:`2020-15999`).

.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/

Deprecations
============

Image._show
^^^^^^^^^^^

``Image._show`` has been deprecated, and will be removed in Pillow 13 (2026-10-15).
Use :py:meth:`~PIL.ImageShow.show` instead.

ImageCms.ImageCmsProfile.product_name and .product_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageCms.ImageCmsProfile.product_name`` and the corresponding
``.product_info`` attributes have been deprecated, and will be removed in
Pillow 13 (2026-10-15). They have been set to ``None`` since Pillow 2.3.0.

API changes
===========

Image.alpha_composite: LA images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.alpha_composite` can now use LA images as well as RGBA.

API additions
=============

Added ImageText.Text
^^^^^^^^^^^^^^^^^^^^

:py:class:`PIL.ImageText.Text` has been added, as a simpler way to use fonts with text
strings or bytes.

Without ``ImageText.Text``::

  from PIL import Image, ImageDraw
  im = Image.new(mode, size)
  d = ImageDraw.Draw(im)

  d.textlength(text, font, direction, features, language, embedded_color)
  d.multiline_textbbox(xy, text, font, anchor, spacing, align, direction, features, language, stroke_width, embedded_color)
  d.text(xy, text, fill, font, anchor, spacing, align, direction, features, language, stroke_width, stroke_fill, embedded_color)

With ``ImageText.Text``::

  from PIL import ImageText
  text = ImageText.Text(text, font, mode, spacing, direction, features, language)
  text.embed_color()
  text.stroke(stroke_width, stroke_fill)

  text.get_length()
  text.get_bbox(xy, anchor, align)

  im = Image.new(mode, size)
  d = ImageDraw.Draw(im)
  d.text(xy, text, fill, anchor=anchor, align=align)

Other changes
=============

Python 3.14
^^^^^^^^^^^

Pillow 11.3.0 had wheels built against Python 3.14 beta, available as a preview to help
others prepare for 3.14, and to ensure Pillow could be used immediately at the release
of 3.14.0 final (2025-10-07, :pep:`745`).

Pillow 12.0.0 now officially supports Python 3.14.

Image.fromarray mode parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In Pillow 11.3.0, the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was
deprecated. Part of this functionality has been restored in Pillow 12.0.0. Since pixel
values do not contain information about palettes or color spaces, the parameter can be
used to place grayscale L mode data within a P mode image, or read RGB data as YCbCr
for example.

ImageMorph operations must have length 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Valid ImageMorph operations are 4, N, 1 and M. By limiting the length to 1 character
within Pillow, long execution times can be avoided if a user provided long pattern
strings. Reported by `Jang Choi <https://github.com/uko3211>`__.
