# Technical Documentation: python-pillow/Pillow

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/python-pillow/Pillow)

### Overview (README.md)

<p align="center">
    <img width="248" height="250" src="https://raw.githubusercontent.com/python-pillow/pillow-logo/main/pillow-logo-248x250.png" alt="Pillow logo">
</p>

# Pillow

## Python Imaging Library (Fork)

Pillow is the friendly PIL fork by [Jeffrey 'Alex' Clark and
contributors](https://github.com/python-pillow/Pillow/graphs/contributors).
PIL is the Python Imaging Library by Fredrik Lundh and contributors.
Development is supported by:
- [Tidelift](https://tidelift.com/lifter/search/pypi/pillow) (since 2018)
- [Thanks.dev](https://thanks.dev) (since 2023)
- [GitHub Sponsors](https://github.com/sponsors/python-pillow) (since 2026)

<table>
    <tr>
        <th>docs</th>
        <td>
            <a href="https://pillow.readthedocs.io/?badge=latest"><img
                alt="Documentation Status"
                src="https://readthedocs.org/projects/pillow/badge/?version=latest"></a>
        </td>
    </tr>
    <tr>
        <th>tests</th>
        <td>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/lint.yml"><img
                alt="GitHub Actions build status (Lint)"
                src="https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg"></a>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/test.yml"><img
                alt="GitHub Actions build status (Test Linux and macOS)"
                src="https://github.com/python-pillow/Pillow/workflows/Test/badge.svg"></a>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-windows.yml"><img
                alt="GitHub Actions build status (Test Windows)"
                src="https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg"></a>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml"><img
                alt="GitHub Actions build status (Test MinGW)"
                src="https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg"></a>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml"><img
                alt="GitHub Actions build status (Test Docker)"
                src="https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg"></a>
            <a href="https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml"><img
                alt="GitHub Actions build status (Wheels)"
                src="https://github.com/python-pillow/Pillow/workflows/Wheels/badge.svg"></a>
            <a href="https://app.codecov.io/gh/python-pillow/Pillow"><img
                alt="Code coverage"
                src="https://codecov.io/gh/python-pillow/Pillow/branch/main/graph/badge.svg"></a>
            <a href="https://issues.oss-fuzz.com/issues?q=title:pillow"><img
                alt="Fuzzing Status"
                src="https://oss-fuzz-build-logs.storage.googleapis.com/badges/pillow.svg"></a>
        </td>
    </tr>
    <tr>
        <th>package</th>
        <td>
            <a href="https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow"><img
                alt="Zenodo"
                src="https://zenodo.org/badge/17549/python-pillow/Pillow.svg"></a>
            <a href="https://tidelift.com/lifter/search/pypi/pillow"><img
                alt="Tidelift"
                src="https://tidelift.com/badges/package/pypi/pillow?style=flat"></a>
            <a href="https://pypi.org/project/pillow/"><img
                alt="Newest PyPI version"
                src="https://img.shields.io/pypi/v/pillow.svg"></a>
            <a href="https://pypi.org/project/pillow/"><img
                alt="Number of PyPI downloads"
                src="https://img.shields.io/pypi/dm/pillow.svg"></a>
            <a href="https://www.bestpractices.dev/projects/6331"><img
                alt="OpenSSF Best Practices"
                src="https://www.bestpractices.dev/projects/6331/badge"></a>
        </td>
    </tr>
    <tr>
        <th>social</th>
        <td>
            <a href="https://fosstodon.org/@pillow"><img
                alt="Follow on https://fosstodon.org/@pillow"
                src="https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg"
                rel="me"></a>
        </td>
    </tr>
</table>

## Overview

The Python Imaging Library adds image processing capabilities to your Python interpreter.

This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.

The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.

## More information

- [Documentation](https://pillow.readthedocs.io/)
  - [Installation](https://pillow.readthedocs.io/en/latest/installation/basic-installation.html)
  - [Handbook](https://pillow.readthedocs.io/en/latest/handbook/index.html)
- [Contribute](https://github.com/python-pillow/Pillow/blob/main/.github/CONTRIBUTING.md)
  - [Issues](https://github.com/python-pillow/Pillow/issues)
  - [Pull requests](https://github.com/python-pillow/Pillow/pulls)
- [Release notes](https://pillow.readthedocs.io/en/stable/releasenotes/index.html)
- [Changelog](https://github.com/python-pillow/Pillow/releases)
  - [Pre-fork](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst#pre-fork)

## Report a vulnerability

To report sensitive vulnerability information, report it [privately on GitHub](https://github.com/python-pillow/Pillow/security/advisories/new).

If you cannot use GitHub, use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.

DO NOT report sensitive vulnerability information in public.

---

### PIL (`docs/PIL.rst`)

PIL package (autodoc of remaining modules)
==========================================

Reference for modules whose documentation has not yet been ported or written
can be found here.

:mod:`PIL` module
-----------------

.. py:module:: PIL

.. autoexception:: UnidentifiedImageError
    :show-inheritance:

:mod:`~PIL.BdfFontFile` module
------------------------------

.. automodule:: PIL.BdfFontFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.ContainerIO` module
------------------------------

.. automodule:: PIL.ContainerIO
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.FontFile` module
---------------------------

.. automodule:: PIL.FontFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GdImageFile` module
------------------------------

.. automodule:: PIL.GdImageFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GimpGradientFile` module
-----------------------------------

.. automodule:: PIL.GimpGradientFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GimpPaletteFile` module
----------------------------------

.. automodule:: PIL.GimpPaletteFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.ImageDraw2` module
-----------------------------

.. automodule:: PIL.ImageDraw2
    :members:
    :member-order: bysource
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.ImageMode` module
----------------------------

.. automodule:: PIL.ImageMode
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PaletteFile` module
------------------------------

.. automodule:: PIL.PaletteFile
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PcfFontFile` module
------------------------------

.. automodule:: PIL.PcfFontFile
    :members:
    :undoc-members:
    :show-inheritance:

:class:`.PngImagePlugin.iTXt` class
-----------------------------------

.. autoclass:: PIL.PngImagePlugin.iTXt
    :members:
    :undoc-members:
    :show-inheritance:

    .. method:: __new__(cls, text, lang, tkey)

        :param value: value for this key
        :param lang: language code
        :param tkey: UTF-8 version of the key name

:class:`.PngImagePlugin.PngInfo` class
--------------------------------------

.. autoclass:: PIL.PngImagePlugin.PngInfo
    :members:
    :undoc-members:
    :show-inheritance:


:mod:`~PIL.TarIO` module
------------------------

.. automodule:: PIL.TarIO
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.WalImageFile` module
-------------------------------

.. automodule:: PIL.WalImageFile
    :members:
    :undoc-members:
    :show-inheritance:

---

### About (`docs/about.rst`)

About
=====

Goals
-----

The fork author's goal is to foster and support active development of PIL through:

- Continuous integration testing via `GitHub Actions`_
- Publicized development activity on `GitHub`_
- Regular releases to the `Python Package Index`_

.. _GitHub Actions: https://github.com/python-pillow/Pillow/actions
.. _GitHub: https://github.com/python-pillow/Pillow
.. _Python Package Index: https://pypi.org/project/pillow/

License
-------

Like PIL, Pillow is `licensed under the open source MIT-CMU License <https://raw.githubusercontent.com/python-pillow/Pillow/main/LICENSE>`_

Why a fork?
-----------

PIL is not setuptools compatible. Please see `this Image-SIG post`_ for a more detailed explanation. Also, PIL's bi-yearly (or greater) release schedule was too infrequent to accommodate the large number and frequency of issues reported.

.. _this Image-SIG post: https://mail.python.org/pipermail/image-sig/2010-August/006480.html

What about PIL?
---------------

.. note::

    Prior to Pillow 2.0.0, very few image code changes were made. Pillow 2.0.0
    added Python 3 support and includes many bug fixes from many contributors.

The last PIL release was in 2009 (1.1.7) and `no future releases are expected <https://github.com/python-pillow/Pillow/issues/1535>`_. In January 2020, `the PyPI moderators exhausted the PEP 541 process for contacting the PIL project owner <https://github.com/python-pillow/Pillow/issues/1535#issuecomment-570308446>`_ and the `PIL project on PyPI <https://pypi.org/project/PIL>`_ was transferred to the `Pillow team <https://github.com/python-pillow/Pillow/graphs/contributors>`_. The Pillow team has no plans to update the PIL project on PyPI.

---

### Deprecations (`docs/deprecations.rst`)

.. _deprecations:

Deprecations and removals
=========================

This page lists Pillow features that are deprecated, or have been removed in
past major releases, and gives the alternatives to use instead.

Deprecated features
-------------------

Below are features which are considered deprecated. Where appropriate,
a :py:exc:`DeprecationWarning` is issued.

Image getdata()
^^^^^^^^^^^^^^^

.. deprecated:: 12.1.0

:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
identical, except that it returns a tuple of pixel values, instead of an internal
Pillow data type.

IM image format
^^^^^^^^^^^^^^^

.. deprecated:: 13.0.0

The IM image format has been deprecated and removal is planned in Pillow 15.0.0
(2028-10-15). If you are using this format and would like to continue doing so,
open an issue about what other software uses it.

ImageQt align8to32()
^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 13.0.0

``ImageQt.align8to32()`` has been deprecated. This was an undocumented helper function
intended for internal use, so there is no replacement.

JpegImageFile.load_djpeg
^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 13.0.0

``JpegImageFile.load_djpeg`` has been deprecated, and will be removed in Pillow 14
(2027-10-15).

Use the built-in JPEG decoder instead, or call ``djpeg`` directly and decode the
resulting image with Pillow.

Removed features
----------------

Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.

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

.. deprecated:: 12.0.0
.. versionremoved:: 13.0.0

``Image._show`` has been removed. Use :py:meth:`~PIL.ImageShow.show` instead.

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

.. deprecated:: 12.0.0
.. versionremoved:: 13.0.0

``ImageCms.ImageCmsProfile.product_name`` and the corresponding
``.product_info`` attributes have been removed. They were set to ``None`` since Pillow
2.3.0.

Saving I mode images as PNG
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.3.0
.. versionremoved:: 13.0.0

In order to fit the 32 bits of I mode images into PNG, when PNG images can only contain
at most 16 bits for a channel, Pillow has been clipping the values. Rather than quietly
changing the data, this is now removed. Instead, the image can be converted to another
mode before saving::

    from PIL import Image
    im = Image.new("I", (1, 1))
    im.convert("I;16").save("out.png")

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

.. deprecated:: 11.3.0
.. versionremoved:: 13.0.0

Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and now the only
functionality removed is when the mode changes data types. Since pixel values do not
contain information about palettes or color spaces, the parameter can still be used to
place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
example. If omitted, the mode will be automatically determined from the object's shape
and type.

Image.Image.get_child_images()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.2.1
.. versionremoved:: 13.0.0

``Image.Image.get_child_images()`` has been 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 :py:class:`PIL.ImageFile.ImageFile`
instance.

ExifTags.IFD.Makernote
^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.1.0
.. versionremoved:: 13.0.0

``ExifTags.IFD.Makernote`` has been removed. Instead, use ``ExifTags.IFD.MakerNote``.

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

.. deprecated:: 10.2.0
.. versionremoved:: 12.0.0

``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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 10.2.0
.. versionremoved:: 12.0.0

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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 10.3.0
.. versionremoved:: 12.0.0

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()
^^^^^^^^^^^^^^^^

.. deprecated:: 10.3.0
.. versionremoved:: 12.0.0

``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
^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0

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

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

.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0

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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0

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

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

.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0

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

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

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.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/

ICNS (width, height, scale) sizes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

Setting an ICNS image size to ``(width, height, scale)`` before loading has been
removed. Instead, ``load(scale)`` can be used.

Image isImageType()
^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

``Image.isImageType(im)`` has been removed. Use ``isinstance(im, Image.Image)``
instead.

ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been removed. One or more keyword
arguments can be used instead.

JpegImageFile.huffman_ac and JpegImageFile.huffman_dc
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

The ``huffman_ac`` and ``huffman_dc`` dictionaries on JPEG images were unused. They
have been removed.

Specific WebP feature checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

``features.check("transp_webp")``, ``features.check("webp_mux")`` and
``features.check("webp_anim")`` have been removed.

Get internal pointers to objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0

``Image.core.ImagingCore.id`` and ``Image.core.ImagingCore.unsafe_ptrs`` have been
removed. They were used for obtaining raw pointers to ``ImagingCore`` internals. To
interact with C code, you can use ``Image.Image.getim()``, which returns a ``Capsule``
object.

TiffImagePlugin IFD_LEGACY_API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionremoved:: 11.0.0

``TiffImagePlugin.IFD_LEGACY_API`` has been removed, as it was an unused setting.

PSFile
~~~~~~

.. deprecated:: 9.5.0
.. versionremoved:: 11.0.0

The :py:class:`!PSFile` class was removed in Pillow 11 (2024-10-15).
This class was only made as a helper to be used internally,
so there is no replacement. If you need this functionality though,
it is a very short class that can easily be recreated in your own code.

PyAccess and Image.USE_CFFI_ACCESS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 10.0.0
.. versionremoved:: 11.0.0

Since Pillow's C API is now faster than PyAccess on PyPy, ``PyAccess`` has been
removed. Pillow's C API will now be used on PyPy instead.

``Image.USE_CFFI_ACCESS``, for switching from the C API to PyAccess, was
similarly removed.

Tk/Tcl 8.4
~~~~~~~~~~

.. deprecated:: 8.2.0
.. versionremoved:: 10.0.0

Support for Tk/Tcl 8.4 was removed in Pillow 10.0.0 (2023-07-01).

Categories
~~~~~~~~~~

.. deprecated:: 8.2.0
.. versionremoved:: 10.0.0

``im.category`` was removed along with the related ``Image.NORMAL``,
``Image.SEQUENCE`` and ``Image.CONTAINER`` attributes.

To determine if an image has multiple frames or not,
``getattr(im, "is_animated", False)`` can be used instead.

JpegImagePlugin.convert_dict_qtables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 8.3.0
.. versionremoved:: 10.0.0

Since deprecation in Pillow 8.3.0, the ``convert_dict_qtables`` method no longer
performed any operations on the data given to it, and has been removed.

ImagePalette size parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 8.4.0
.. versionremoved:: 10.0.0

Before Pillow 8.3.0, ``ImagePalette`` required palette data of particular lengths by
default, and the ``size`` parameter could be used to override that. Pillow 8.3.0
removed the default required length, also removing the need for the ``size`` parameter.

ImageShow.Viewer.show_file file argument
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 9.1.0
.. versionremoved:: 10.0.0

The ``file`` argument in :py:meth:`~PIL.ImageShow.Viewer.show_file()` has been
removed and replaced by ``path``.

In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.

Constants
~~~~~~~~~

.. deprecated:: 9.1.0
.. versionremoved:: 10.0.0

A number of constants have been removed.
Instead, :py:class:`enum.IntEnum` classes have been added.

.. note::

    Additional ``Image`` constants were deprecated in Pillow 9.1.0, but that
    was reversed in Pillow 9.4.0 and those constants will now remain available.
    See :ref:`restored-image-constants`

=====================================================  ============================================================
Removed                                                Use instead
=====================================================  ============================================================
``Image.LINEAR``                                       ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
``Image.CUBIC``                                        ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
``Image.ANTIALIAS``                                    ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
``ImageCms.INTENT_PERCEPTUAL``                         ``ImageCms.Intent.PERCEPTUAL``
``ImageCms.INTENT_RELATIVE_COLORMETRIC``               ``ImageCms.Intent.RELATIVE_COLORMETRIC``
``ImageCms.INTENT_SATURATION``                         ``ImageCms.Intent.SATURATION``
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``              ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
``ImageCms.DIRECTION_INPUT``                           ``ImageCms.Direction.INPUT``
``ImageCms.DIRECTION_OUTPUT``                          ``ImageCms.Direction.OUTPUT``
``ImageCms.DIRECTION_PROOF``                           ``ImageCms.Direction.PROOF``
``ImageFont.LAYOUT_BASIC``                             ``ImageFont.Layout.BASIC``
``ImageFont.LAYOUT_RAQM``                              ``ImageFont.Layout.RAQM``
``BlpImagePlugin.BLP_FORMAT_JPEG``                     ``BlpImagePlugin.Format.JPEG``
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED``           ``BlpImagePlugin.Encoding.UNCOMPRESSED``
``BlpImagePlugin.BLP_ENCODING_DXT``                    ``BlpImagePlugin.Encoding.DXT``
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA``  ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1``             ``BlpImagePlugin.AlphaEncoding.DXT1``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3``             ``BlpImagePlugin.AlphaEncoding.DXT3``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5``             ``BlpImagePlugin.AlphaEncoding.DXT5``
``FtexImagePlugin.FORMAT_DXT1``                        ``FtexImagePlugin.Format.DXT1``
``FtexImagePlugin.FORMAT_UNCOMPRESSED``                ``FtexImagePlugin.Format.UNCOMPRESSED``
``PngImagePlugin.APNG_DISPOSE_OP_NONE``                ``PngImagePlugin.Disposal.OP_NONE``
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND``          ``PngImagePlugin.Disposal.OP_BACKGROUND``
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS``            ``PngImagePlugin.Disposal.OP_PREVIOUS``
``PngImagePlugin.APNG_BLEND_OP_SOURCE``                ``PngImagePlugin.Blend.OP_SOURCE``
``PngImagePlugin.APNG_BLEND_OP_OVER``                  ``PngImagePlugin.Blend.OP_OVER``
=====================================================  ============================================================

FitsStubImagePlugin
~~~~~~~~~~~~~~~~~~~

.. deprecated:: 9.1.0
.. versionremoved:: 10.0.0

The stub image plugin ``FitsStubImagePlugin`` has been removed.
FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead.

Font size and offset methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 9.2.0
.. versionremoved:: 10.0.0

Several functions for computing the size and offset of rendered text have been removed:

=============================================================== =============================================================================================================
Removed                                                         Use instead
=============================================================== =============================================================================================================
``FreeTypeFont.getsize()`` and ``FreeTypeFont.getoffset()``     :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength`
``FreeTypeFont.getsize_multiline()``                            :py:meth:`.ImageDraw.multiline_textbbox`
``ImageFont.getsize()``                                         :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength`
``TransposedFont.getsize()``                                    :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength`
``ImageDraw.textsize()`` and ``ImageDraw.multiline_textsize()`` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox`
``ImageDraw2.Draw.textsize()``                                  :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength`
=============================================================== =============================================================================================================

Previous code::

    from PIL import Image, ImageDraw, ImageFont

    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")
    width, height = font.getsize("Hello world")
    left, top = font.getoffset("Hello world")

    im = Image.new("RGB", (100, 100))
    draw = ImageDraw.Draw(im)
    width, height = draw.textsize("Hello world", font)

    width, height = font.getsize_multiline("Hello\nworld")
    width, height = draw.multiline_textsize("Hello\nworld", font)

Use instead::

    from PIL import Image, ImageDraw, ImageFont

    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")
    left, top, right, bottom = font.getbbox("Hello world")
    width, height = right - left, bottom - top

    im = Image.new("RGB", (100, 100))
    draw = ImageDraw.Draw(im)
    width = draw.textlength("Hello world", font)

    left, top, right, bottom = draw.multiline_textbbox((0, 0), "Hello\nworld", font)
    width, height = right - left, bottom - top

Previously, the ``size`` methods returned a ``height`` that included the vertical
offset of the text, while the new ``bbox`` methods distinguish this as a ``top``
offset.

.. image:: ./example/size_vs_bbox.webp
    :alt: In bbox methods, top measures the vertical distance above the text, while bottom measures that plus the vertical distance of the text itself. In size methods, height also measures the vertical distance above the text plus the vertical distance of the text itself.
    :align: center

If you are using these methods for aligning text, consider using :ref:`text-anchors` instead
which avoid issues that can occur with non-English text or unusual fonts.
For example, instead of the following code::

    from PIL import Image, ImageDraw, ImageFont

    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

    im = Image.new("RGB", (100, 100))
    draw = ImageDraw.Draw(im)
    width, height = draw.textsize("Hello world", font)
    x, y = (100 - width) / 2, (100 - height) / 2
    draw.text((x, y), "Hello world", font=font)

Use instead::

    from PIL import Image, ImageDraw, ImageFont

    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

    im = Image.new("RGB", (100, 100))
    draw = ImageDraw.Draw(im)
    draw.text((100 / 2, 100 / 2), "Hello world", font=font, anchor="mm")

FreeTypeFont.getmask2 fill parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 9.2.0
.. versionremoved:: 10.0.0

The undocumented ``fill`` parameter of :py:meth:`.FreeTypeFont.getmask2` has been
removed.

PhotoImage.paste box parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 9.2.0
.. versionremoved:: 10.0.0

The ``box`` parameter was unused and has been removed.

PyQt5 and PySide2
~~~~~~~~~~~~~~~~~

.. deprecated:: 9.2.0
.. versionremoved:: 10.0.0

`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).

Support for PyQt5 and PySide2 has been removed from ``ImageQt``. Upgrade to
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
`PySide6 <https://doc.qt.io/qtforpython-6/>`_ instead.

Image.coerce_e
~~~~~~~~~~~~~~

.. deprecated:: 9.2.0
.. versionremoved:: 10.0.0

This undocumented method has been removed.

PILLOW_VERSION constant
~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 5.2.0
.. versionremoved:: 9.0.0

Use ``__version__`` instead.

It was initially removed in Pillow 7.0.0, but temporarily brought back in 7.1.0
to give projects more time to upgrade.

Image.show command parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 7.2.0
.. versionremoved:: 9.0.0

The ``command`` parameter has been removed. Use a subclass of
:py:class:`.ImageShow.Viewer` instead.

Image._showxv
~~~~~~~~~~~~~

.. deprecated:: 7.2.0
.. versionremoved:: 9.0.0

Use :py:meth:`.Image.Image.show` instead. If custom behaviour is required, use
:py:func:`.ImageShow.register` to add a custom :py:class:`.ImageShow.Viewer` class.

ImageFile.raise_ioerror
~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 7.2.0
.. versionremoved:: 9.0.0

:py:exc:`IOError` was merged into :py:exc:`OSError` in Python 3.3.
So, ``ImageFile.raise_ioerror`` has been removed.
Use ``ImageFile.raise_oserror`` instead.

FreeType 2.7
~~~~~~~~~~~~

.. deprecated:: 8.1.0
.. versionremoved:: 9.0.0

Support for FreeType 2.7 has been removed.

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

.. _FreeType: https://freetype.org/

im.offset
~~~~~~~~~

.. deprecated:: 1.1.2
.. versionremoved:: 8.0.0

``im.offset()`` has been removed, call :py:func:`.ImageChops.offset()` instead.

It was documented as deprecated in PIL 1.1.2,
raised a :py:exc:`DeprecationWarning` since 1.1.5,
an :py:exc:`Exception` since Pillow 3.0.0
and :py:exc:`NotImplementedError` since 3.3.0.

Image.fromstring, im.fromstring and im.tostring
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 2.0.0
.. versionremoved:: 8.0.0

* ``Image.fromstring()`` has been removed, call :py:func:`.Image.frombytes()` instead.
* ``im.fromstring()`` has been removed, call :py:meth:`~PIL.Image.Image.frombytes()` instead.
* ``im.tostring()`` has been removed, call :py:meth:`~PIL.Image.Image.tobytes()` instead.

They issued a :py:exc:`DeprecationWarning` since 2.0.0,
an :py:exc:`Exception` since 3.0.0
and :py:exc:`NotImplementedError` since 3.3.0.

ImageCms.CmsProfile attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 3.2.0
.. versionremoved:: 8.0.0

Some attributes in :py:class:`PIL.ImageCms.core.CmsProfile` have been removed.
From 6.0.0, they issued a :py:exc:`DeprecationWarning`:

========================  ===================================================
Removed                   Use instead
========================  ===================================================
``color_space``           Padded :py:attr:`~.CmsProfile.xcolor_space`
``pcs``                   Padded :py:attr:`~.CmsProfile.connection_space`
``product_copyright``     Unicode :py:attr:`~.CmsProfile.copyright`
``product_desc``          Unicode :py:attr:`~.CmsProfile.profile_description`
``product_description``   Unicode :py:attr:`~.CmsProfile.profile_description`
``product_manufacturer``  Unicode :py:attr:`~.CmsProfile.manufacturer`
``product_model``         Unicode :py:attr:`~.CmsProfile.model`
========================  ===================================================

Python 2.7
~~~~~~~~~~

.. deprecated:: 6.0.0
.. versionremoved:: 7.0.0

Python 2.7 reached end-of-life on 2020-01-01. Pillow 6.x was the last series to
support Python 2.

Image.__del__
~~~~~~~~~~~~~

.. deprecated:: 6.1.0
.. versionremoved:: 7.0.0

Implicitly closing the image's underlying file in ``Image.__del__`` has been removed.
Use a context manager or call ``Image.close()`` instead to close the file in a
deterministic way.

Previous method::

    im = Image.open("hopper.png")
    im.save("out.jpg")

Use instead::

    with Image.open("hopper.png") as im:
        im.save("out.jpg")

PIL.*ImagePlugin.__version__ attributes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 6.0.0
.. versionremoved:: 7.0.0

The version constants of individual plugins have been removed. Use ``PIL.__version__``
instead.

===============================  =================================  ==================================
Removed                          Removed                            Removed
===============================  =================================  ==================================
``BmpImagePlugin.__version__``   ``Jpeg2KImagePlugin.__version__``  ``PngImagePlugin.__version__``
``CurImagePlugin.__version__``   ``JpegImagePlugin.__version__``    ``PpmImagePlugin.__version__``
``DcxImagePlugin.__version__``   ``McIdasImagePlugin.__version__``  ``PsdImagePlugin.__version__``
``EpsImagePlugin.__version__``   ``MicImagePlugin.__version__``     ``SgiImagePlugin.__version__``
``FliImagePlugin.__version__``   ``MpegImagePlugin.__version__``    ``SunImagePlugin.__version__``
``FpxImagePlugin.__version__``   ``MpoImagePlugin.__version__``     ``TgaImagePlugin.__version__``
``GdImageFile.__version__``      ``MspImagePlugin.__version__``     ``TiffImagePlugin.__version__``
``GifImagePlugin.__version__``   ``PalmImagePlugin.__version__``    ``WmfImagePlugin.__version__``
``IcoImagePlugin.__version__``   ``PcdImagePlugin.__version__``     ``XbmImagePlugin.__version__``
``ImImagePlugin.__version__``    ``PcxImagePlugin.__version__``     ``XpmImagePlugin.__version__``
``ImtImagePlugin.__version__``   ``PdfImagePlugin.__version__``     ``XVThumbImagePlugin.__version__``
``IptcImagePlugin.__version__``  ``PixarImagePlugin.__version__``
===============================  =================================  ==================================

PyQt4 and PySide
~~~~~~~~~~~~~~~~

.. deprecated:: 6.0.0
.. versionremoved:: 7.0.0

Qt 4 reached end-of-life on 2015-12-19. Its Python bindings are also EOL: PyQt4 since
2018-08-31 and PySide since 2015-10-14.

Support for PyQt4 and PySide has been removed from ``ImageQt``. Please upgrade to PyQt5
or PySide2.

Setting the size of TIFF images
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 5.3.0
.. versionremoved:: 7.0.0

Setting the size of a TIFF image directly (eg. ``im.size = (256, 256)``) throws
an error. Use ``Image.resize`` instead.

VERSION constant
~~~~~~~~~~~~~~~~

.. deprecated:: 5.2.0
.. versionremoved:: 6.0.0

``VERSION`` (the old PIL version, always 1.1.7) has been removed. Use
``__version__`` instead.

Undocumented ImageOps functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 4.3.0
.. versionremoved:: 6.0.0

Several undocumented functions in ``ImageOps`` have been removed. Use the equivalents
in ``ImageFilter`` instead:

==========================  ============================
Removed                     Use instead
==========================  ============================
``ImageOps.box_blur``       ``ImageFilter.BoxBlur``
``ImageOps.gaussian_blur``  ``ImageFilter.GaussianBlur``
``ImageOps.gblur``          ``ImageFilter.GaussianBlur``
``ImageOps.usm``            ``ImageFilter.UnsharpMask``
``ImageOps.unsharp_mask``   ``ImageFilter.UnsharpMask``
==========================  ============================

PIL.OleFileIO
~~~~~~~~~~~~~

.. deprecated:: 4.0.0
.. versionremoved:: 6.0.0

``PIL.OleFileIO`` was removed as a vendored file in Pillow 4.0.0 (2017-01) in favour of
the upstream :pypi:`olefile` Python package, and replaced with an :py:exc:`ImportError` in 5.0.0
(2018-01). The deprecated file has now been removed from Pillow. If needed, install from
PyPI (eg. ``python3 -m pip install olefile``).

import _imaging
~~~~~~~~~~~~~~~

.. versionremoved:: 2.1.0

Pillow >= 2.1.0 no longer supports ``import _imaging``.
Please use ``from PIL.Image import core as _imaging`` instead.

Pillow and PIL
~~~~~~~~~~~~~~

.. versionremoved:: 1.0.0

Pillow and PIL cannot co-exist in the same environment.
Before installing Pillow, please uninstall PIL.

import Image
~~~~~~~~~~~~

.. versionremoved:: 1.0.0

Pillow >= 1.0 no longer supports ``import Image``.
Please use ``from PIL import Image`` instead.

---

### Index (`docs/index.rst`)

Pillow
======

Pillow is the friendly PIL fork by `Jeffrey 'Alex' Clark and contributors <https://github.com/python-pillow/Pillow/graphs/contributors>`_. PIL is the Python Imaging Library by Fredrik Lundh and contributors.

Pillow for enterprise is available via the Tidelift Subscription. `Learn more <https://tidelift.com/lifter/search/pypi/pillow>`_.

.. image:: https://readthedocs.org/projects/pillow/badge/?version=latest
   :target: https://pillow.readthedocs.io/?badge=latest
   :alt: Documentation Status

.. image:: https://github.com/python-pillow/Pillow/workflows/Lint/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/lint.yml
   :alt: GitHub Actions build status (Lint)

.. image:: https://github.com/python-pillow/Pillow/workflows/Test%20Docker/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/test-docker.yml
   :alt: GitHub Actions build status (Test Docker)

.. image:: https://github.com/python-pillow/Pillow/workflows/Test/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/test.yml
   :alt: GitHub Actions build status (Test Linux and macOS)

.. image:: https://github.com/python-pillow/Pillow/workflows/Test%20Windows/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/test-windows.yml
   :alt: GitHub Actions build status (Test Windows)

.. image:: https://github.com/python-pillow/Pillow/workflows/Test%20MinGW/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/test-mingw.yml
   :alt: GitHub Actions build status (Test MinGW)

.. image:: https://github.com/python-pillow/Pillow/workflows/Wheels/badge.svg
   :target: https://github.com/python-pillow/Pillow/actions/workflows/wheels.yml
   :alt: GitHub Actions build status (Wheels)

.. image:: https://codecov.io/gh/python-pillow/Pillow/branch/main/graph/badge.svg
   :target: https://app.codecov.io/gh/python-pillow/Pillow
   :alt: Code coverage

.. image:: https://zenodo.org/badge/17549/python-pillow/Pillow.svg
   :target: https://zenodo.org/badge/latestdoi/17549/python-pillow/Pillow
   :alt: Zenodo

.. image:: https://tidelift.com/badges/package/pypi/pillow?style=flat
   :target: https://tidelift.com/lifter/search/pypi/pillow
   :alt: Tidelift

.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/pillow.svg
   :target: https://issues.oss-fuzz.com/issues?q=title:pillow
   :alt: Fuzzing Status

.. image:: https://img.shields.io/pypi/v/pillow.svg
   :target: https://pypi.org/project/pillow/
   :alt: Latest PyPI version

.. image:: https://img.shields.io/pypi/dm/pillow.svg
   :target: https://pypi.org/project/pillow/
   :alt: Number of PyPI downloads

.. image:: https://www.bestpractices.dev/projects/6331/badge
   :target: https://www.bestpractices.dev/projects/6331
   :alt: OpenSSF Best Practices

.. image:: https://img.shields.io/badge/publish-on%20Mastodon-595aff.svg
   :target: https://fosstodon.org/@pillow
   :alt: Follow on https://fosstodon.org/@pillow

.. raw:: html

   <link rel="me" href="https://fosstodon.org/@pillow">

Overview
========

The Python Imaging Library adds image processing capabilities to your Python interpreter.

This library provides extensive file format support, an efficient internal representation, and fairly powerful image processing capabilities.

The core image library is designed for fast access to data stored in a few basic pixel formats. It should provide a solid foundation for a general image processing tool.

.. toctree::
   :maxdepth: 2

   installation/index.rst
   handbook/index.rst
   reference/index.rst
   porting.rst
   about.rst
   releasenotes/index.rst
   deprecations.rst

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`

---

### Installation (`docs/installation.rst`)

:orphan:

Installation
============

Basic installation
------------------

.. Note:: This section has moved to :ref:`basic-installation`. Please update references accordingly.

Python support
--------------

.. Note:: This section has moved to :ref:`python-support`. Please update references accordingly.

Platform support
----------------

.. Note:: This section has moved to :ref:`platform-support`. Please update references accordingly.

Building from source
--------------------

.. Note:: This section has moved to :ref:`building-from-source`. Please update references accordingly.

Old versions
------------

.. Note:: This section has moved to :ref:`old-versions`. Please update references accordingly.

---

### Porting (`docs/porting.rst`)

Porting
=======

**Porting existing PIL-based code to Pillow**

Pillow is a functional drop-in replacement for the Python Imaging Library.

PIL is Python 2 only. Pillow dropped support for Python 2 in Pillow
7.0. So if you would like to run the latest version of Pillow, you will first
and foremost need to port your code from Python 2 to 3.

To run your existing PIL-compatible code with Pillow, it needs to be modified
to import the ``Image`` module from the ``PIL`` namespace *instead* of the
global namespace. Change this::

    import Image

to this::

    from PIL import Image

The :py:mod:`PIL._imaging` module has been moved to :py:mod:`PIL.Image.core`.
You can now import it like this::

    from PIL.Image import core as _imaging

The image plugin loading mechanism has changed. Pillow no longer
automatically imports any file in the Python path with a name ending
in :file:`ImagePlugin.py`. You will need to import your image plugin
manually.

Pillow will raise an exception if the core extension can't be loaded
for any reason, including a version mismatch between the Python and
extension code. Previously PIL allowed Python only code to run if the
core extension was not available.

---

### Handbook Appendices (`docs/handbook/appendices.rst`)

Appendices
==========

.. note:: Contributors please include appendices as needed or appropriate with your bug fixes, feature additions and tests.

.. toctree::
  :maxdepth: 2

  image-file-formats
  text-anchors
  third-party-plugins
  writing-your-own-image-plugin

---

### Handbook Concepts (`docs/handbook/concepts.rst`)

Concepts
========

The Python Imaging Library handles *raster images*; that is, rectangles of
pixel data.

.. _concept-bands:

Bands
-----

An image can consist of one or more bands of data. The Python Imaging Library
allows you to store several bands in a single image, provided they all have the
same dimensions and depth.  For example, a PNG image might have 'R', 'G', 'B',
and 'A' bands for the red, green, blue, and alpha transparency values.  Many
operations act on each band separately, e.g., histograms.  It is often useful to
think of each pixel as having one value per band.

To get the number and names of bands in an image, use the
:py:meth:`~PIL.Image.Image.getbands` method.

.. _concept-modes:

Modes
-----

The ``mode`` of an image is a string which defines the type and depth of a pixel in the
image. Each pixel uses the full range of the bit depth. So a 1-bit pixel has a range of
0-1, an 8-bit pixel has a range of 0-255, a 32-signed integer pixel has the range of
INT32 and a 32-bit floating point pixel has the range of FLOAT32. The current release
supports the following standard modes:

* ``1`` (1-bit pixels, black and white, stored with one pixel per byte)
* ``L`` (8-bit pixels, grayscale)
* ``P`` (8-bit pixels, mapped to any other mode using a color palette)
* ``RGB`` (3x8-bit pixels, true color)
* ``RGBA`` (4x8-bit pixels, true color with transparency mask)
* ``CMYK`` (4x8-bit pixels, color separation)
* ``YCbCr`` (3x8-bit pixels, color video format)

  * Note that this refers to the JPEG, and not the ITU-R BT.2020, standard

* ``LAB`` (3x8-bit pixels, the L*a*b color space)
* ``HSV`` (3x8-bit pixels, Hue, Saturation, Value color space)

  * Hue's range of 0-255 is a scaled version of 0 degrees <= Hue < 360 degrees

* ``I`` (32-bit signed integer pixels)
* ``F`` (32-bit floating point pixels)

Pillow also provides limited support for a few additional modes, including:

* ``LA`` (L with alpha)
* ``PA`` (P with alpha)
* ``RGBX`` (true color with padding)
* ``RGBa`` (true color with premultiplied alpha)
* ``La`` (L with premultiplied alpha)
* ``I;16`` (16-bit unsigned integer pixels)
* ``I;16L`` (16-bit little endian unsigned integer pixels)
* ``I;16B`` (16-bit big endian unsigned integer pixels)
* ``I;16N`` (16-bit native endian unsigned integer pixels)

Premultiplied alpha is where the values for each other channel have been
multiplied by the alpha. For example, an RGBA pixel of ``(10, 20, 30, 127)``
would convert to an RGBa pixel of ``(5, 10, 15, 127)``. The values of the R,
G and B channels are halved as a result of the half transparency in the alpha
channel.

Apart from these additional modes, Pillow doesn't yet support multichannel
images with a depth of more than 8 bits per channel.

Pillow also doesn’t support user-defined modes; if you need to handle band
combinations that are not listed above, use a sequence of Image objects.

You can read the mode of an image through the :py:attr:`~PIL.Image.Image.mode`
attribute. This is a string containing one of the above values.

Size
----

You can read the image size through the :py:attr:`~PIL.Image.Image.size`
attribute. This is a 2-tuple, containing the horizontal and vertical size in
pixels.

.. _coordinate-system:

Coordinate system
-----------------

The Python Imaging Library uses a Cartesian pixel coordinate system, with (0,0)
in the upper left corner. Note that the coordinates refer to the implied pixel
corners; the centre of a pixel addressed as (0, 0) actually lies at (0.5, 0.5).

Coordinates are usually passed to the library as 2-tuples (x, y). Rectangles
are represented as 4-tuples, (x1, y1, x2, y2), with the upper left corner given
first.

Palette
-------

The palette mode (``P``) uses a color palette to define the actual color for
each pixel.

.. _colors:

Colors
------

To specify colors, you can use tuples with a value for each channel in the image, e.g.
``Image.new("RGB", (1, 1), (255, 0, 0))``.

If an image has a single channel, you can use a single number instead, e.g.
``Image.new("L", (1, 1), 255)``. For "F" mode images, floating point values are also
accepted. In the case of "P" mode images, these will be indexes for the color palette.

If a single value is used for an image with more than one channel, it will still be
parsed::

    >>> from PIL import Image
    >>> im = Image.new("RGBA", (1, 1), 0x04030201)
    >>> im.getpixel((0, 0))
    (1, 2, 3, 4)

Some methods accept other forms, such as color names. See :ref:`color-names`.

Info
----

You can attach auxiliary information to an image using the
:py:attr:`~PIL.Image.Image.info` attribute. This is a dictionary object.

How such information is handled when loading and saving image files is up to
the file format handler (see the chapter on :ref:`image-file-formats`). Most
handlers add properties to the :py:attr:`~PIL.Image.Image.info` attribute when
loading an image, but ignore it when saving images.

Transparency
------------

If an image does not have an alpha band, transparency may be specified in the
:py:attr:`~PIL.Image.Image.info` attribute with a "transparency" key.

Most of the time, the "transparency" value is a single integer, describing
which pixel value is transparent in a "1", "L", "I" or "P" mode image.
However, PNG images may have three values, one for each channel in an "RGB"
mode image, or can have a byte string for a "P" mode image, to specify the
alpha value for each palette entry.

Orientation
-----------

A common element of the :py:attr:`~PIL.Image.Image.info` attribute for JPG and
TIFF images is the EXIF orientation tag. This is an instruction for how the
image data should be oriented. For example, it may instruct an image to be
rotated by 90 degrees, or to be mirrored. To apply this information to an
image, :py:meth:`~PIL.ImageOps.exif_transpose` can be used.

.. _concept-filters:

Filters
-------

For geometry operations that may map multiple input pixels to a single output
pixel, the Python Imaging Library provides different resampling *filters*.

.. py:currentmodule:: PIL.Image

.. data:: Resampling.NEAREST
    :noindex:

    Pick one nearest pixel from the input image. Ignore all other input pixels.

.. data:: Resampling.BOX
    :noindex:

    Each pixel of the source image contributes to one pixel of the
    destination image with identical weights.
    For upscaling, this is equivalent to :data:`Resampling.NEAREST`.
    This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
    and :py:meth:`~PIL.Image.Image.thumbnail` methods.

    .. versionadded:: 3.4.0

.. data:: Resampling.BILINEAR
    :noindex:

    For resize, calculate the output pixel value using linear interpolation
    on all pixels that may contribute to the output value.
    For other transformations linear interpolation over a 2x2 environment
    in the input image is used.

.. data:: Resampling.HAMMING
    :noindex:

    Produces a sharper image than :data:`Resampling.BILINEAR`, doesn't have
    dislocations on local level like with :data:`Resampling.BOX`.
    This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
    and :py:meth:`~PIL.Image.Image.thumbnail` methods.

    .. versionadded:: 3.4.0

.. data:: Resampling.BICUBIC
    :noindex:

    For resize, calculate the output pixel value using cubic interpolation
    on all pixels that may contribute to the output value.
    For other transformations cubic interpolation over a 4x4 environment
    in the input image is used.

.. data:: Resampling.LANCZOS
    :noindex:

    Calculate the output pixel value using a high-quality Lanczos filter (a
    truncated sinc) on all pixels that may contribute to the output value.
    This filter can only be used with the :py:meth:`~PIL.Image.Image.resize`
    and :py:meth:`~PIL.Image.Image.thumbnail` methods.

    .. versionadded:: 1.1.3

.. data:: Resampling.MKS2013
    :noindex:

    Calculate the output pixel value using the Magic Kernel Sharp 2013 filter
    (a quadratic B-spline composed with a sharpening kernel) on all pixels that
    may contribute to the output value. This filter can only be used with the
    :py:meth:`~PIL.Image.Image.resize` and :py:meth:`~PIL.Image.Image.thumbnail`
    methods.

    .. versionadded:: 13.0.0

.. data:: Resampling.MKS2021
    :noindex:

    Calculate the output pixel value using the Magic Kernel Sharp 2021 filter
    (a quadratic B-spline composed with a sharpening kernel) on all pixels that
    may contribute to the output value. This filter can only be used with the
    :py:meth:`~PIL.Image.Image.resize` and :py:meth:`~PIL.Image.Image.thumbnail`
    methods.

    .. versionadded:: 13.0.0

Filters comparison table
~~~~~~~~~~~~~~~~~~~~~~~~

+---------------------------+-------------+-----------+-------------+
| Filter                    | Downscaling | Upscaling | Performance |
|                           | quality     | quality   |             |
+===========================+=============+===========+=============+
|:data:`Resampling.NEAREST` |             |           | ⭐⭐⭐⭐⭐  |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BOX`     | ⭐          |           | ⭐⭐⭐⭐    |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BILINEAR`| ⭐          | ⭐        | ⭐⭐⭐      |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.HAMMING` | ⭐⭐        |           | ⭐⭐⭐      |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BICUBIC` | ⭐⭐⭐      | ⭐⭐⭐    | ⭐⭐        |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.LANCZOS` | ⭐⭐⭐⭐    | ⭐⭐⭐⭐  | ⭐          |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.MKS2013` | ⭐⭐⭐⭐    | ⭐⭐⭐⭐  | ⭐          |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.MKS2021` | ⭐⭐⭐⭐⭐  | ⭐⭐⭐⭐⭐| ⭐          |
+---------------------------+-------------+-----------+-------------+

---

### Handbook Image File Formats (`docs/handbook/image-file-formats.rst`)

.. _image-file-formats:

Image file formats
==================

The Python Imaging Library supports a wide variety of raster file formats.
Over 30 different file formats can be identified and read by the library.
Write support is less extensive, but most common interchange and presentation
formats are supported.

The :py:meth:`~PIL.Image.open` function identifies files from their
contents, not their names, but the :py:meth:`~PIL.Image.Image.save` method
looks at the name to determine which format to use, unless the format is given
explicitly.

When an image is opened from a file, only that instance of the image is considered to
have the format. Copies of the image will contain data loaded from the file, but not
the file itself, meaning that it can no longer be considered to be in the original
format. So if :py:meth:`~PIL.Image.Image.copy` is called on an image, or another method
internally creates a copy of the image, then any methods or attributes specific to the
format will no longer be present. The ``fp`` (file pointer) attribute will no longer be
present, and the :py:attr:`~PIL.Image.Image.format` attribute will be ``None``.

Fully supported formats
-----------------------

AVIF
^^^^

Pillow reads and writes AVIF files, including AVIF sequence images.
It is only possible to save 8-bit AVIF images, and all AVIF images are decoded
as 8-bit RGB(A).

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**icc_profile**
    May not be present. The ICC color profile for the image.

**exif**
    May not be present. Raw EXIF data from the image.

**xmp**
    May not be present. Raw XMP data from the image.

**duration**
    Only present after the current frame is loaded. The time to display the current
    frame of the AVIF sequence, in milliseconds.

**timestamp**
    Only present after the current frame is loaded. The time of the current frame
    within the AVIF sequence, in milliseconds.

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**quality**
    Integer, 0-100, defaults to 75. 0 gives the smallest size and poorest
    quality, 100 the largest size and best quality.

**subsampling**
    If present, sets the subsampling for the encoder. If absent, and all frames are in
    grayscale mode without alpha, ``4:0:0`` is used. Otherwise defaults to ``4:2:0``.
    Options include:

    * ``4:0:0``
    * ``4:2:0``
    * ``4:2:2``
    * ``4:4:4``

**speed**
    Quality/speed trade-off (0=slower/better, 10=fastest). Defaults to 6.

**max_threads**
    Limit the number of active threads used. By default, there is no limit. If the aom
    codec is used, there is a maximum of 64.

**range**
    YUV range, either "full" or "limited". Defaults to "full".

**codec**
    AV1 codec to use for encoding. Specific values are "aom", "rav1e", and
    "svt", presuming the chosen codec is available. Defaults to "auto", which
    will choose the first available codec in the order of the preceding list.

**tile_rows** / **tile_cols**
    For tile encoding, the (log 2) number of tile rows and columns to use.
    Valid values are 0-6, default 0. Ignored if "autotiling" is set to true.

**autotiling**
    Split the image up to allow parallelization. Enabled automatically if "tile_rows"
    and "tile_cols" both have their default values of zero.

**alpha_premultiplied**
    Encode the image with premultiplied alpha. Defaults to ``False``.

**advanced**
    Codec specific options.

**icc_profile**
    The ICC Profile to include in the saved file.

**exif**
    The exif data to include in the saved file.

**xmp**
    The XMP data to include in the saved file.

Saving sequences
~~~~~~~~~~~~~~~~

When calling :py:meth:`~PIL.Image.Image.save` to write an AVIF file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
argument is present and true, then all frames will be saved, and the following
options will also be available.

**append_images**
    A list of images to append as additional frames. Each of the
    images in the list can be single or multiframe images.

**duration**
    The display duration of each frame, in milliseconds. Pass a single
    integer for a constant duration, or a list or tuple to set the
    duration for each frame separately.

BLP
^^^

BLP is the Blizzard Mipmap Format, a texture format used in World of
Warcraft. Pillow supports reading ``JPEG`` Compressed or raw ``BLP1``
images, and all types of ``BLP2`` images.

Saving
~~~~~~

Pillow supports writing BLP images. The :py:meth:`~PIL.Image.Image.save` method
can take the following keyword arguments:

**blp_version**
    If present and set to "BLP1", images will be saved as BLP1. Otherwise, images
    will be saved as BLP2.

BMP
^^^

Pillow reads and writes Windows and OS/2 BMP files containing ``1``, ``L``, ``P``,
or ``RGB`` data. 16-colour images are read as ``P`` images.
Support for reading 8-bit run-length encoding was added in Pillow 9.1.0.
Support for reading 4-bit run-length encoding was added in Pillow 9.3.0.

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**compression**
    Set to 1 if the file is a 256-color run-length encoded image.
    Set to 2 if the file is a 16-color run-length encoded image.

DDS
^^^

DDS is a popular container texture format used in video games and natively supported
by DirectX.

DXT1 and DXT5 pixel formats can be read, only in ``RGBA`` mode.

.. versionadded:: 3.4.0
   DXT3 images can be read in ``RGBA`` mode and DX10 images can be read in
   ``RGB`` and ``RGBA`` mode.

.. versionadded:: 6.0.0
   Uncompressed ``RGBA`` images can be read.


.. versionadded:: 8.3.0
   BC5S images can be opened in ``RGB`` mode, and uncompressed ``RGB`` images
   can be read. Uncompressed data can also be saved to image files.


.. versionadded:: 9.3.0
   ATI1 images can be opened in ``L`` mode and ATI2 images can be opened in
   ``RGB`` mode.

.. versionadded:: 9.4.0
   Uncompressed ``L`` ("luminance") and ``LA`` images can be opened and saved.


.. versionadded:: 10.1.0
   BC5U can be read in ``RGB`` mode, and 8-bit color indexed images can be read
   in ``P`` mode.


.. versionadded:: 11.2.1
   DXT1, DXT3, DXT5, BC2, BC3 and BC5 pixel formats can be saved::

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


DIB
^^^

Pillow reads and writes DIB files. DIB files are similar to BMP files, so see
above for more information.

    .. versionadded:: 6.0.0

EPS
^^^

Pillow identifies EPS files containing image data, and can read files that
contain embedded raster images (ImageData descriptors). If Ghostscript is
available, other EPS files can be read as well. The EPS driver can also write
EPS images. The EPS driver can read EPS images in ``L``, ``LAB``, ``RGB`` and
``CMYK`` mode, but Ghostscript may convert the images to ``RGB`` mode rather
than leaving them in the original color space. The EPS driver can write images
in ``L``, ``RGB`` and ``CMYK`` modes.

Loading
~~~~~~~

To use Ghostscript, Pillow searches for the "gs" executable. On Windows, it
also searches for "gswin32c" and "gswin64c". To customise this behaviour,
``EpsImagePlugin.gs_binary = "gswin64"`` will set the name of the executable to
use. ``EpsImagePlugin.gs_binary = False`` will prevent Ghostscript use.

If Ghostscript is available, you can call the :py:meth:`~PIL.Image.Image.load`
method with the following parameters to affect how Ghostscript renders the EPS.

**scale**
    Affects the scale of the resultant rasterized image. If the EPS suggests
    that the image be rendered at 100px x 100px, setting this parameter to
    2 will make the Ghostscript render a 200px x 200px image instead. The
    relative position of the bounding box is maintained::

        im = Image.open(...)
        im.size  # (100,100)
        im.load(scale=2)
        im.size  # (200,200)

**transparency**
    If true, generates an RGBA image with a transparent background, instead of
    the default behaviour of an RGB image with a white background.


GIF
^^^

Pillow reads GIF87a and GIF89a versions of the GIF file format. The library
writes files in GIF87a by default, unless GIF89a features are used or GIF89a is
already in use. Files are written with LZW encoding.

GIF files are initially read as grayscale (``L``) or palette mode (``P``)
images. Seeking to later frames in a ``P`` image will change the image to
``RGB`` (or ``RGBA`` if the first frame had transparency).

``P`` mode images are changed to ``RGB`` because each frame of a GIF may contain
its own individual palette of up to 256 colors. When a new frame is placed onto a
previous frame, those colors may combine to exceed the ``P`` mode limit of 256
colors. Instead, the image is converted to ``RGB`` to handle this.

If you would prefer the first ``P`` image frame to be ``RGB`` as well, so that
every ``P`` frame is converted to ``RGB`` or ``RGBA`` mode, there is a setting
available::

    from PIL import GifImagePlugin
    GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_ALWAYS

GIF frames do not always contain individual palettes however. If there is only
a global palette, then all of the colors can fit within ``P`` mode. If you would
prefer the frames to be kept as ``P`` in that case, there is also a setting
available::

    from PIL import GifImagePlugin
    GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY

To restore the default behavior, where ``P`` mode images are only converted to
``RGB`` or ``RGBA`` after the first frame::

    from PIL import GifImagePlugin
    GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST

.. _gif-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**background**
    Default background color (a palette color index).

**transparency**
    Transparency color index. This key is omitted if the image is not
    transparent.

**version**
    Version (either ``GIF87a`` or ``GIF89a``).

**duration**
    May not be present. The time to display the current frame
    of the GIF, in milliseconds.

**loop**
    May not be present. The number of times the GIF should loop. 0 means that
    it will loop forever.

**comment**
    May not be present. A comment about the image. This is the last comment found
    before the current frame's image.

**extension**
    May not be present. Contains application specific information.

Reading sequences
~~~~~~~~~~~~~~~~~

The GIF loader supports the :py:meth:`~PIL.Image.Image.seek` and
:py:meth:`~PIL.Image.Image.tell` methods. You can combine these methods
to seek to the next frame (``im.seek(im.tell() + 1)``).

``im.seek()`` raises an :py:exc:`EOFError` if you try to seek after the last frame.

.. _gif-saving:

Saving
~~~~~~

When calling :py:meth:`~PIL.Image.Image.save` to write a GIF file, the
following options are available::

    im.save(out, save_all=True, append_images=[im1, im2, ...])

**save_all**
    If present and true, or if ``append_images`` is not empty, all frames of
    the image will be saved. Otherwise, only the first frame of a multiframe
    image will be saved.

**append_images**
    A list of images to append as additional frames. Each of the
    images in the list can be single or multiframe images.
    This is supported for AVIF, GIF, PDF, PNG, TIFF and WebP.

    It is also supported for ICO and ICNS. If images are passed in of relevant
    sizes, they will be used instead of scaling down the main image.

**include_color_table**
    Whether or not to include local color table.

**interlace**
    Whether or not the image is interlaced. By default, it is, unless the image
    is less than 16 pixels in width or height.

**disposal**
    Indicates the way in which the graphic is to be treated after being displayed.

    * 0 - No disposal specified.
    * 1 - Do not dispose.
    * 2 - Restore to background color.
    * 3 - Restore to previous content.

     Pass a single integer for a constant disposal, or a list or tuple
     to set the disposal for each frame separately.

**palette**
    Use the specified palette for the saved image. The palette should
    be a bytes or bytearray object containing the palette entries in
    RGBRGB... form. It should be no more than 768 bytes. Alternatively,
    the palette can be passed in as an
    :py:class:`PIL.ImagePalette.ImagePalette` object.

**optimize**
    Whether to attempt to compress the palette by eliminating unused colors
    (this is only useful if the palette can be compressed to the next smaller
    power of 2 elements) and whether to mark all pixels that are not new in the
    next frame as transparent.

    This is attempted by default, unless a palette is specified as an option or
    as part of the first image's :py:attr:`~PIL.Image.Image.info` dictionary.

Note that if the image you are saving comes from an existing GIF, it may have
the following properties in its :py:attr:`~PIL.Image.Image.info` dictionary.
For these options, if you do not pass them in, they will default to
their :py:attr:`~PIL.Image.Image.info` values.

**transparency**
    Transparency color index.

**duration**
    The display duration of each frame of the multiframe gif, in
    milliseconds. Pass a single integer for a constant duration, or a
    list or tuple to set the duration for each frame separately.

**loop**
    Integer number of times the GIF should loop. 0 means that it will loop
    forever. If omitted or ``None``, the image will not loop.

**comment**
    A comment about the image.

Reading local images
~~~~~~~~~~~~~~~~~~~~

The GIF loader creates an image memory the same size as the GIF file’s *logical
screen size*, and pastes the actual pixel data (the *local image*) into this
image. If you only want the actual pixel rectangle, you can crop the image::

    im = Image.open(...)

    if im.tile[0][0] == "gif":
        # only read the first "local image" from this GIF file
        box = im.tile[0][1]
        im = im.crop(box)

ICNS
^^^^

Pillow reads and writes macOS ``.icns`` files.  By default, the
largest available icon is read, though you can override this by setting the
:py:attr:`~PIL.Image.Image.size` property before calling
:py:meth:`~PIL.Image.Image.load`.  The :py:meth:`~PIL.Image.open` method
sets the following :py:attr:`~PIL.Image.Image.info` property:

.. note::

    Prior to version 8.3.0, Pillow could only write ICNS files on macOS.

**sizes**
    A list of supported sizes found in this icon file; these are a
    3-tuple, ``(width, height, scale)``, where ``scale`` is 2 for a retina
    icon and 1 for a standard icon.

.. _icns-loading:

Loading
~~~~~~~

You can call the :py:meth:`~PIL.Image.Image.load` method with the following parameter.

**scale**
    Affects the scale of the resultant image. If the size is set to ``(512, 512)``,
    after loading at scale 2, the final value of :py:attr:`~PIL.Image.Image.size` will
    be ``(1024, 1024)``.

.. _icns-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**append_images**
    A list of images to replace the scaled down versions of the image.
    The order of the images does not matter, as their use is determined by
    the size of each image.

    .. versionadded:: 5.1.0

ICO
^^^

ICO is used to store icons on Windows. The largest available icon is read.

.. _ico-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**sizes**
    A list of sizes included in this ico file; these are a 2-tuple,
    ``(width, height)``; Default to ``[(16, 16), (24, 24), (32, 32), (48, 48),
    (64, 64), (128, 128), (256, 256)]``, or if it is smaller, only the image size.
    Any sizes bigger than the original size or 256 will be ignored.

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**append_images**
    A list of images to replace the scaled down versions of the image.
    The order of the images does not matter, as their use is determined by
    the size of each image.

    .. versionadded:: 8.1.0

**bitmap_format**
    By default, the image data will be saved in PNG format. With a bitmap format of
    "bmp", image data will be saved in BMP format instead.

    .. versionadded:: 8.3.0

IM
^^

.. deprecated:: 13.0.0

IM is a format used by LabEye and other applications based on the IFUNC image
processing library. The library reads and writes most uncompressed interchange
versions of this format.

IM is the only format that can store all internal Pillow formats.

JPEG
^^^^

Pillow reads JPEG, JFIF, and Adobe JPEG files containing ``L``, ``RGB``, or
``CMYK`` data. It writes standard and progressive JFIF files.

Using the :py:meth:`~PIL.Image.Image.draft` method, you can speed things up by
converting ``RGB`` images to ``L``, and resize images to 1/2, 1/4 or 1/8 of
their original size while loading them.

By default Pillow doesn't allow loading of truncated JPEG files, set
:data:`.ImageFile.LOAD_TRUNCATED_IMAGES` to override this.

.. _jpeg-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method may set the following
:py:attr:`~PIL.Image.Image.info` properties if available:

**jfif**
    JFIF application marker found. If the file is not a JFIF file, this key is
    not present.

**jfif_version**
    A tuple representing the jfif version, (major version, minor version).

**jfif_density**
    A tuple representing the pixel density of the image, in units specified
    by jfif_unit.

**jfif_unit**
    Units for the jfif_density:

    * 0 - No Units
    * 1 - Pixels per Inch
    * 2 - Pixels per Centimeter

**dpi**
    A tuple representing the reported pixel density in pixels per inch, if
    the file is a jfif file and the units are in inches.

**adobe**
    Adobe application marker found. If the file is not an Adobe JPEG file, this
    key is not present.

**adobe_transform**
    Vendor Specific Tag.

**progression**
    Indicates that this is a progressive JPEG file.

**icc_profile**
    The ICC color profile for the image.

**exif**
    Raw EXIF data from the image.

**comment**
    A comment about the image, from the COM marker. This is separate from the
    UserComment tag that may be stored in the EXIF data.

    .. versionadded:: 7.1.0

.. _jpeg-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**quality**
    The image quality, on a scale from 0 (worst) to 95 (best), or the string
    ``keep``. The default is 75. Values above 95 should be avoided; 100 disables
    portions of the JPEG compression algorithm, and results in large files with
    hardly any gain in image quality. The value ``keep`` is only valid for JPEG
    files and will retain the original image quality level, subsampling, and
    qtables.
    For more information on how qtables are modified based on the quality parameter,
    see the qtables section.

**optimize**
    If present and true, indicates that the encoder should make an extra pass
    over the image in order to select optimal encoder settings.

**progressive**
    If present and true, indicates that this image should be stored as a
    progressive JPEG file.

**dpi**
    A tuple of integers representing the pixel density, ``(x,y)``.

**icc_profile**
    If present and true, the image is stored with the provided ICC profile.
    If this parameter is not provided, the image will be saved with no profile
    attached. To preserve the existing profile::

        im.save(filename, 'jpeg', icc_profile=im.info.get('icc_profile'))

**exif**
    If present, the image will be stored with the provided raw EXIF data.

**keep_rgb**
    By default, libjpeg converts images with an RGB color space to YCbCr.
    If this option is present and true, those images will be stored as RGB
    instead.

    When this option is enabled, attempting to chroma-subsample RGB images
    with the ``subsampling`` option will raise an :py:exc:`OSError`.

    .. versionadded:: 10.2.0

**subsampling**
    If present, sets the subsampling for the encoder.

    * ``keep``: Only valid for JPEG files, will retain the original image setting.
    * ``4:4:4``, ``4:2:2``, ``4:2:0``: Specific sampling values
    * ``0``: equivalent to ``4:4:4``
    * ``1``: equivalent to ``4:2:2``
    * ``2``: equivalent to ``4:2:0``

    If absent, the setting will be determined by libjpeg or libjpeg-turbo.

**restart_marker_blocks**
    If present, emit a restart marker whenever the specified number of MCU
    blocks has been produced.

    .. versionadded:: 10.2.0

**restart_marker_rows**
    If present, emit a restart marker whenever the specified number of MCU
    rows has been produced.

    .. versionadded:: 10.2.0

**qtables**
    If present, sets the qtables for the encoder. This is listed as an
    advanced option for wizards in the JPEG documentation. Use with
    caution. ``qtables`` can be one of several types of values:

    *  a string, naming a preset, e.g. ``keep``, ``web_low``, or ``web_high``
    *  a list, tuple, or dictionary (with integer keys =
       range(len(keys))) of lists of 64 integers. There must be
       between 2 and 4 tables.

    If a quality parameter is provided, the qtables will be adjusted accordingly.
    By default, the qtables are based on a standard JPEG table with a quality of 50.
    The qtable values will be reduced if the quality is higher than 50 and increased
    if the quality is lower than 50.

    .. versionadded:: 2.5.0

**streamtype**
    Allows storing images without quantization and Huffman tables, or with
    these tables but without image data.  This is useful for container formats
    or network protocols that handle tables separately and share them between
    images.

    * ``0`` (default): interchange datastream, with tables and image data
    * ``1``: abbreviated table specification (tables-only) datastream

      .. versionadded:: 10.2.0

    * ``2``: abbreviated image (image-only) datastream

**comment**
    A comment about the image.

    .. versionadded:: 9.4.0


.. note::

    To enable JPEG support, you need to build and install the IJG JPEG library
    before building the Python Imaging Library. See the distribution README for
    details.

JPEG 2000
^^^^^^^^^

.. versionadded:: 2.4.0

Pillow reads and writes JPEG 2000 files containing ``L``, ``LA``, ``RGB``,
``RGBA``, or ``YCbCr`` data.  When reading, ``YCbCr`` data is converted to
``RGB`` or ``RGBA`` depending on whether or not there is an alpha channel.

.. versionadded:: 8.3.0
   Pillow can read (but not write) ``RGB``, ``RGBA``, and ``YCbCr`` images with
   subsampled components.

.. versionadded:: 10.4.0
   Pillow can read ``CMYK`` images with OpenJPEG 2.5.1 and later.

.. versionadded:: 11.1.0
   Pillow can write ``CMYK`` images with OpenJPEG 2.5.3 and later.

Pillow supports JPEG 2000 raw codestreams (``.j2k`` files), as well as boxed
JPEG 2000 files (``.jp2`` or ``.jpx`` files).

When loading, if you set the ``mode`` on the image prior to the
:py:meth:`~PIL.Image.Image.load` method being invoked, you can ask Pillow to
convert the image to either ``RGB`` or ``RGBA`` rather than choosing for
itself.  It is also possible to set ``reduce`` to the number of resolutions to
discard (each one reduces the size of the resulting image by a factor of 2),
and ``layers`` to specify the number of quality layers to load.

.. _jpeg-2000-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**offset**
    The image offset, as a tuple of integers, e.g. (16, 16)

**tile_offset**
    The tile offset, again as a 2-tuple of integers.

**tile_size**
    The tile size as a 2-tuple.  If not specified, or if set to None, the
    image will be saved without tiling.

**quality_mode**
    Either ``"rates"`` or ``"dB"`` depending on the units you want to use to
    specify image quality.

**quality_layers**
    A sequence of numbers, each of which represents either an approximate size
    reduction (if quality mode is ``"rates"``) or a signal to noise ratio value
    in decibels.  If not specified, defaults to a single layer of full quality.

**num_resolutions**
    The number of different image resolutions to be stored (which corresponds
    to the number of Discrete Wavelet Transform decompositions plus one).

**codeblock_size**
    The code-block size as a 2-tuple.  Minimum size is 4 x 4, maximum is 1024 x
    1024, with the additional restriction that no code-block may have more
    than 4096 coefficients (i.e. the product of the two numbers must be no
    greater than 4096).

**precinct_size**
    The precinct size as a 2-tuple.  Must be a power of two along both axes,
    and must be greater than the code-block size.

**irreversible**
    If ``True``, use the lossy discrete waveform transformation DWT 9-7.
    Defaults to ``False``, which uses the lossless DWT 5-3.

**mct**
    If ``1`` then enable multiple component transformation when encoding,
    otherwise use ``0`` for no component transformation (default). If MCT is
    enabled and ``irreversible`` is ``True`` then the Irreversible Color
    Transformation will be applied, otherwise encoding will use the
    Reversible Color Transformation. MCT works best with a ``mode`` of
    ``RGB`` and is only applicable when the image data has 3 components.

    .. versionadded:: 9.1.0

**progression**
    Controls the progression order; must be one of ``"LRCP"``, ``"RLCP"``,
    ``"RPCL"``, ``"PCRL"``, ``"CPRL"``.  The letters stand for Component,
    Position, Resolution and Layer respectively and control the order of
    encoding, the idea being that e.g. an image encoded using LRCP mode can
    have its quality layers decoded as they arrive at the decoder, while one
    encoded using RLCP mode will have increasing resolutions decoded as they
    arrive, and so on.

**signed**
    If true, then tell the encoder to save the image as signed.

    .. versionadded:: 9.4.0

**cinema_mode**
    Set the encoder to produce output compliant with the digital cinema
    specifications.  The options here are ``"no"`` (the default),
    ``"cinema2k-24"`` for 24fps 2K, ``"cinema2k-48"`` for 48fps 2K, and
    ``"cinema4k-24"`` for 24fps 4K.  Note that for compliant 2K files,
    *at least one* of your image dimensions must match 2048 x 1080, while
    for compliant 4K files, *at least one* of the dimensions must match
    4096 x 2160.

**no_jp2**
    If ``True`` then don't wrap the raw codestream in the JP2 file format when
    saving, otherwise the extension of the filename will be used to determine
    the format (default).

    .. versionadded:: 9.1.0

**comment**
    Adds a custom comment to the file, replacing the default
    "Created by OpenJPEG version" comment.

    .. versionadded:: 9.5.0

**plt**
    If ``True`` and OpenJPEG 2.4.0 or later is available, then include a PLT
    (packet length, tile-part header) marker in the produced file.
    Defaults to ``False``.

    .. versionadded:: 9.5.0

.. note::

   To enable JPEG 2000 support, you need to build and install the OpenJPEG
   library, version 2.0.0 or higher, before building the Python Imaging
   Library.

   Windows users can install the OpenJPEG binaries available on the
   OpenJPEG website, but must add them to their PATH in order to use Pillow (if
   you fail to do this, you will get errors about not being able to load the
   ``_imaging`` DLL).

MPO
^^^

Pillow reads and writes Multi Picture Object (MPO) files. When first opened, it loads
the primary image. The :py:meth:`~PIL.Image.Image.seek` and
:py:meth:`~PIL.Image.Image.tell` methods may be used to read other pictures from the
file. The pictures are zero-indexed and random access is supported.

.. _mpo-saving:

Saving
~~~~~~

When calling :py:meth:`~PIL.Image.Image.save` to write an MPO file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
argument is present and true, or if ``append_images`` is not empty, all frames
will be saved.

**append_images**
    A list of images to append as additional pictures. Each of the
    images in the list can be single or multiframe images.

    .. versionadded:: 9.3.0

MSP
^^^

Pillow identifies and reads MSP files from Windows 1 and 2. The library writes
uncompressed (Windows 1) versions of this format.

PCX
^^^

Pillow reads and writes PCX files containing ``1``, ``L``, ``P``, or ``RGB`` data.

Opening
~~~~~~~

The :py:func:`~PIL.Image.open` function sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**scale**
    The absolute value of the number stored in the *Scale Factor / Endianness* line.

PNG
^^^

Pillow identifies, reads, and writes PNG files containing ``1``, ``L``, ``LA``,
``I``, ``P``, ``RGB`` or ``RGBA`` data. Interlaced files are supported as of
v1.1.7.

As of Pillow 6.0, EXIF data can be read from PNG images. However, unlike other
image formats, EXIF data is not guaranteed to be present in
:py:attr:`~PIL.Image.Image.info` until :py:meth:`~PIL.Image.Image.load` has been
called.

By default Pillow doesn't allow loading of truncated PNG files, set
:data:`.ImageFile.LOAD_TRUNCATED_IMAGES` to override this.

.. _png-opening:

Opening
~~~~~~~

The :py:func:`~PIL.Image.open` function sets the following
:py:attr:`~PIL.Image.Image.info` properties, when appropriate:

**chromaticity**
    The chromaticity points, as an 8 tuple of floats. (``White Point
    X``, ``White Point Y``, ``Red X``, ``Red Y``, ``Green X``, ``Green
    Y``, ``Blue X``, ``Blue Y``)

**gamma**
    Gamma, given as a floating point number.

**srgb**
    The sRGB rendering intent as an integer.

      * 0 Perceptual
      * 1 Relative Colorimetric
      * 2 Saturation
      * 3 Absolute Colorimetric

**transparency**
    For ``P`` images: Either the palette index for full transparent pixels,
    or a byte string with alpha values for each palette entry.

    For ``1``, ``L``, ``I`` and ``RGB`` images, the color that represents
    full transparent pixels in this image.

    This key is omitted if the image is not a transparent palette image.

.. _png-text:

``open`` also sets ``Image.text`` to a dictionary of the values of the
``tEXt``, ``zTXt``, and ``iTXt`` chunks of the PNG image. Individual
compressed chunks are limited to a decompressed size of
:data:`.PngImagePlugin.MAX_TEXT_CHUNK`, by default 1MB, to prevent
decompression bombs. Additionally, the total size of all of the text
chunks is limited to :data:`.PngImagePlugin.MAX_TEXT_MEMORY`, defaulting to
64MB.

.. _png-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**optimize**
    If present and true, instructs the PNG writer to make the output file as
    small as possible. This includes extra processing in order to find optimal
    encoder settings.

**transparency**
    For ``P``, ``1``, ``L``, ``I``, and ``RGB`` images, this option controls
    what color from the image to mark as transparent.

    For ``P`` images, this can be a either the palette index,
    or a byte string with alpha values for each palette entry.

**dpi**
    A tuple of two numbers corresponding to the desired dpi in each direction.

**pnginfo**
    A :py:class:`PIL.PngImagePlugin.PngInfo` instance containing chunks.

**compress_level**
    ZLIB compression level, a number between 0 and 9: 1 gives best speed,
    9 gives best compression, 0 gives no compression at all. Default is 6.
    When ``optimize`` option is True ``compress_level`` has no effect
    (it is set to 9 regardless of a value passed).

**compress_type**
    ZLIB compression strategy, one of the strategy constants from Python's
    :py:mod:`zlib` module: ``zlib.Z_DEFAULT_STRATEGY`` (0), ``zlib.Z_FILTERED`` (1),
    ``zlib.Z_HUFFMAN_ONLY`` (2), ``zlib.Z_RLE`` (3) or ``zlib.Z_FIXED`` (4). For ``P``
    images, defaults to ``zlib.Z_DEFAULT_STRATEGY`` (0). Otherwise defaults to
    ``zlib.Z_FILTERED`` (1).

**icc_profile**
    The ICC Profile to include in the saved file.

**exif**
    The exif data to include in the saved file.

    .. versionadded:: 6.0.0

**bits (experimental)**
    For ``L`` and ``P`` images, this option controls how many bits to store. If
    omitted, the PNG writer uses 8 bits (256 colors). The ``PLTE`` chunk only contains
    as many entries as the image's palette actually has, rather than being padded with
    zeroes up to ``2 ** bits``.

**dictionary (experimental)**
    Set the ZLIB encoder dictionary.

.. note::

    To enable PNG support, you need to build and install the ZLIB compression
    library before building the Python Imaging Library. See the
    :doc:`installation documentation <../installation>` for details.

.. _apng-sequences:

APNG sequences
~~~~~~~~~~~~~~

The PNG loader includes limited support for reading and writing Animated Portable
Network Graphics (APNG) files.
When an APNG file is loaded, :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype`
will return ``"image/apng"``. The value of the :py:attr:`~PIL.Image.Image.is_animated`
property will be ``True`` when the :py:attr:`~PIL.Image.Image.n_frames` property is
greater than 1. For APNG files, the ``n_frames`` property depends on both the animation
frame count as well as the presence or absence of a default image. See the
``default_image`` property documentation below for more details.
The :py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods
are supported.

``im.seek()`` raises an :py:exc:`EOFError` if you try to seek after the last frame.

These :py:attr:`~PIL.Image.Image.info` properties will be set for APNG frames,
where applicable:

**default_image**
    Specifies whether or not this APNG file contains a separate default image,
    which is not a part of the actual APNG animation.

    When an APNG file contains a default image, the initially loaded image (i.e.
    the result of ``seek(0)``) will be the default image.
    To account for the presence of the default image, the
    :py:attr:`~PIL.Image.Image.n_frames` property will be set to ``frame_count + 1``,
    where ``frame_count`` is the actual APNG animation frame count.
    To load the first APNG animation frame, ``seek(1)`` must be called.

    * ``True`` - The APNG contains default image, which is not an animation frame.
    * ``False`` - The APNG does not contain a default image. The ``n_frames`` property
      will be set to the actual APNG animation frame count.
      The initially loaded image (i.e. ``seek(0)``) will be the first APNG animation
      frame.

**loop**
    The number of times to loop this APNG, 0 indicates infinite looping.

**duration**
    The time to display this APNG frame (in milliseconds), given as a float.

.. note::

    The APNG loader returns images the same size as the APNG file's logical screen size.
    The returned image contains the pixel data for a given frame, after applying
    any APNG frame disposal and frame blend operations (i.e. it contains what a web
    browser would render for this frame - the composite of all previous frames and this
    frame).

    Any APNG file containing sequence errors is treated as an invalid image. The APNG
    loader will not attempt to repair and reorder files containing sequence errors.

.. _apng-saving:

Saving
~~~~~~

When calling :py:meth:`~PIL.Image.Image.save`, by default only a single frame PNG file
will be saved. To save an APNG file (including a single frame APNG), the ``save_all``
parameter should be set to ``True`` or ``append_images`` should not be empty. The
following parameters can also be set:

**default_image**
    Boolean value, specifying whether or not the base image is a default image.
    If ``True``, the base image will be used as the default image, and the first image
    from the ``append_images`` sequence will be the first APNG animation frame.
    If ``False``, the base image will be used as the first APNG animation frame.
    Defaults to ``False``.

**append_images**
    A list or tuple of images to append as additional frames. Each of the
    images in the list can be single or multiframe images. The size of each frame
    should match the size of the base image. Also note that if a frame's mode does
    not match that of the base image, the frame will be converted to the base image
    mode.

**loop**
    Integer number of times to loop this APNG, 0 indicates infinite looping.
    Defaults to 0.

**duration**
    The length of time (or list or tuple of lengths of time) to display this APNG frame
    (in milliseconds). Defaults to 0.

**disposal**
    An integer (or list or tuple of integers) specifying the APNG disposal
    operation to be used for this frame before rendering the next frame.
    Defaults to 0.

    * 0 (:py:data:`~PIL.PngImagePlugin.Disposal.OP_NONE`, default) -
      No disposal is done on this frame before rendering the next frame.
    * 1 (:py:data:`PIL.PngImagePlugin.Disposal.OP_BACKGROUND`) -
      This frame's modified region is cleared to fully transparent black before
      rendering the next frame.
    * 2 (:py:data:`~PIL.PngImagePlugin.Disposal.OP_PREVIOUS`) -
      This frame's modified region is reverted to the previous frame's contents before
      rendering the next frame.

**blend**
    An integer (or list or tuple of integers) specifying the APNG blend
    operation to be used for this frame before rendering the next frame.
    Defaults to 0.

    * 0 (:py:data:`~PIL.PngImagePlugin.Blend.OP_SOURCE`) -
      All color components of this frame, including alpha, overwrite the previous output
      image contents.
    * 1 (:py:data:`~PIL.PngImagePlugin.Blend.OP_OVER`) -
      This frame should be alpha composited with the previous output image contents.

.. note::

    The ``duration``, ``disposal`` and ``blend`` parameters can be set to lists or tuples to
    specify values for each individual frame in the animation. The length of the list or tuple
    must be identical to the total number of actual frames in the APNG animation.
    If the APNG contains a default image (i.e. ``default_image`` is set to ``True``),
    these list or tuple parameters should not include an entry for the default image.


PPM
^^^

Pillow reads and writes PBM, PGM, PPM, PNM and PFM files containing ``1``, ``L``, ``I``,
``RGB`` or ``F`` data.

"Raw" (P4 to P6) formats can be read, and are used when writing.

.. versionadded:: 9.2.0
   "Plain" (P1 to P3) formats can be read.

.. versionadded:: 10.3.0
   Grayscale (Pf format) Portable FloatMap (PFM) files containing
   ``F`` data can be read and used when writing.

Color (PF format) PFM files are not supported.

QOI
^^^

.. versionadded:: 9.5.0

Pillow reads and writes images in Quite OK Image format using a Python codec. If you
wish to write code specifically for this format, :pypi:`qoi` is an alternative library
that uses C to decode the image and interfaces with NumPy.

.. _qoi-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**colorspace**
    If set to "sRGB", the colorspace will be written as sRGB with linear alpha, instead
    of all channels being linear.

SGI
^^^

Pillow reads uncompressed and RLE compressed ``L``, ``RGB``, and ``RGBA`` files,
with either 8-bit or 16-bit channels. It writes uncompressed files.

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**bpc**
    The number of bytes per channel. Use ``1`` (the default) to save each channel as
    8-bit, or ``2`` to save each channel as 16-bit.


SPIDER
^^^^^^

Pillow reads and writes SPIDER image files of 32-bit floating point data
("F;32F").

Pillow also reads SPIDER stack files containing sequences of SPIDER images. The
:py:meth:`~PIL.Image.Image.seek` and :py:meth:`~PIL.Image.Image.tell` methods are supported, and
random access is allowed.

.. _spider-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following attributes:

**format**
    Set to ``SPIDER``

**istack**
    Set to 1 if the file is an image stack, else 0.

**n_frames**
    Set to the number of images in the stack.

A convenience method, :py:meth:`~PIL.SpiderImagePlugin.SpiderImageFile.convert2byte`,
is provided for converting floating point data to byte data (mode ``L``)::

    im = Image.open("image001.spi").convert2byte()

.. _spider-saving:

Saving
~~~~~~

The extension of SPIDER files may be any 3 alphanumeric characters. Therefore
the output format must be specified explicitly::

    im.save('newimage.spi', format='SPIDER')

For more information about the SPIDER image processing package, see
https://github.com/spider-em/SPIDER

TGA
^^^

Pillow reads and writes TGA images containing ``L``, ``LA``, ``P``,
``RGB``, and ``RGBA`` data. Pillow can read and write both uncompressed and
run-length encoded TGAs.

.. _tga-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**compression**
    If set to "tga_rle", the file will be run-length encoded.

    .. versionadded:: 5.3.0

**id_section**
    The identification field.

    .. versionadded:: 5.3.0

**orientation**
    If present and a positive number, the first pixel is for the top left corner,
    rather than the bottom left corner.

    .. versionadded:: 5.3.0

TIFF
^^^^

Pillow reads and writes TIFF files. It can read both striped and tiled
images, pixel and plane interleaved multi-band images. If you have
libtiff and its headers installed, Pillow can read and write many kinds
of compressed TIFF files. If not, Pillow will only read and write
uncompressed files.

.. note::

    Beginning in version 5.0.0, Pillow requires libtiff to read or
    write compressed files. Prior to that release, Pillow had buggy
    support for reading Packbits, LZW and JPEG compressed TIFFs
    without using libtiff.

.. _tiff-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**compression**
    Compression mode.

    .. versionadded:: 2.0.0

**dpi**
    Image resolution as an ``(xdpi, ydpi)`` tuple, where applicable. You can use
    the :py:attr:`~PIL.TiffImagePlugin.TiffImageFile.tag` attribute to get more
    detailed information about the image resolution.

    .. versionadded:: 1.1.5

**resolution**
    Image resolution as an ``(xres, yres)`` tuple, where applicable. This is a
    measurement in whichever unit is specified by the file.

    .. versionadded:: 1.1.5


The :py:attr:`~PIL.TiffImagePlugin.TiffImageFile.tag_v2` attribute contains a
dictionary of TIFF metadata. The keys are numerical indexes from
:py:data:`.TiffTags.TAGS_V2`.  Values are strings or numbers for single
items, multiple values are returned in a tuple of values. Rational
numbers are returned as a :py:class:`~PIL.TiffImagePlugin.IFDRational`
object.

    .. versionadded:: 3.0.0

For compatibility with legacy code, the
:py:attr:`~PIL.TiffImagePlugin.TiffImageFile.tag` attribute contains a dictionary
of decoded TIFF fields as returned prior to version 3.0.0.  Values are
returned as either strings or tuples of numeric values. Rational
numbers are returned as a tuple of ``(numerator, denominator)``.

    .. deprecated:: 3.0.0

Reading multi-frame TIFF images
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The TIFF loader supports the :py:meth:`~PIL.Image.Image.seek` and
:py:meth:`~PIL.Image.Image.tell` methods, taking and returning frame numbers
within the image file. You can combine these methods to seek to the next frame
(``im.seek(im.tell() + 1)``). Frames are numbered from 0 to ``im.n_frames - 1``,
and can be accessed in any order.

``im.seek()`` raises an :py:exc:`EOFError` if you try to seek after the
last frame.

.. _tiff-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**save_all**
    If true, or if ``append_images`` is not empty, Pillow will save all frames of the
    image to a multiframe tiff document.

    .. versionadded:: 3.4.0

**append_images**
    A list of images to append as additional frames. Each of the
    images in the list can be single or multiframe images.

    .. versionadded:: 4.2.0

**tiffinfo**
    A :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` object or dict
    object containing tiff tags and values. The TIFF field type is
    autodetected for Numeric and string values, any other types
    require using an :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2`
    object and setting the type in
    :py:attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype` with
    the appropriate numerical value from
    :py:data:`.TiffTags.TYPES`.

    .. versionadded:: 2.3.0

    Metadata values that are of the rational type should be passed in
    using a :py:class:`~PIL.TiffImagePlugin.IFDRational` object.

    .. versionadded:: 3.1.0

    For compatibility with legacy code, a
    :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` object may
    be passed in this field. However, this is deprecated.

    .. versionadded:: 5.4.0

    Previous versions only supported some tags when writing using
    libtiff. The supported list is found in
    :py:data:`.TiffTags.LIBTIFF_CORE`.

    .. versionadded:: 6.1.0

    Added support for signed types (e.g. ``TIFF_SIGNED_LONG``) and multiple values.
    Multiple values for a single tag must be passed to
    :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` as a tuple and
    require a matching type in
    :py:attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype` tagtype.

**exif**
    Alternate keyword to "tiffinfo", for consistency with other formats.

    .. versionadded:: 8.4.0

**big_tiff**
    If true, the image will be saved as a BigTIFF.

    .. versionadded:: 11.1.0

**compression**
    A string containing the desired compression method for the
    file. (valid only with libtiff installed) Valid compression
    methods are: :data:`None`, ``"group3"``, ``"group4"``, ``"jpeg"``, ``"lzma"``,
    ``"packbits"``, ``"tiff_adobe_deflate"``, ``"tiff_ccitt"``, ``"tiff_lzw"``,
    ``"tiff_raw_16"``, ``"tiff_sgilog"``, ``"tiff_sgilog24"``, ``"tiff_thunderscan"``,
    ``"webp"``, ``"zstd"``

**quality**
    The image quality for JPEG compression, on a scale from 0 (worst) to 100
    (best). The default is 75.

    .. versionadded:: 6.1.0

**strip_size**
    When saving with libtiff, the requested size of each strip in bytes. The default is
    65536. The strip size is controlled by using this value to calculate the
    RowsPerStrip tag. This can be overridden by setting the RowsPerStrip tag directly
    instead.

These arguments to set the tiff header fields are an alternative to
using the general tags available through tiffinfo.

**description**

**software**

**date_time**

**artist**

**copyright**
    Strings

**icc_profile**
    The ICC Profile to include in the saved file.

**resolution_unit**
    An integer. 1 for no unit, 2 for inches and 3 for centimeters.

**resolution**
    Either an integer or a float, used for both the x and y resolution.

**x_resolution**
    Either an integer or a float.

**y_resolution**
    Either an integer or a float.

**dpi**
    A tuple of ``(x_resolution, y_resolution)``, with inches as the resolution
    unit. For consistency with other image formats, the x and y resolutions
    of the dpi will be rounded to the nearest integer.


WebP
^^^^

Pillow reads and writes WebP files. Requires libwebp v0.5.0 or later.

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**background**
    Background color of the canvas, as an RGBA tuple with values in
    the range of (0-255).

**loop**
    The number of times the WEBP should loop. 0 means that it will loop forever.

**icc_profile**
    May not be present. The ICC color profile for the image.

**exif**
    May not be present. Raw EXIF data from the image.

**xmp**
    May not be present. Raw XMP data from the image.

**duration**
    Only present after the current frame is loaded. The time to display the current
    frame of the WEBP, in milliseconds.

**timestamp**
    Only present after the current frame is loaded. The total duration of all previous
    frames of the WEBP, in milliseconds.

.. _webp-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method supports the following options:

**lossless**
    If present and true, instructs the WebP writer to use lossless compression.

**quality**
    Integer, 0-100, defaults to 80. For lossy, 0 gives the smallest
    size and 100 the largest. For lossless, this parameter is the amount
    of effort put into the compression: 0 is the fastest, but gives larger
    files compared to the slowest, but best, 100.

**alpha_quality**
    Integer, 0-100, defaults to 100. For lossy compression only. 0 gives the
    smallest size and 100 is lossless.

**method**
    Quality/speed trade-off (0=fast, 6=slower-better). Defaults to 4.

**exact**
    If true, preserve the transparent RGB values. Otherwise, discard
    invisible RGB values for better compression. Defaults to false.

**icc_profile**
    The ICC Profile to include in the saved file.

**exif**
    The exif data to include in the saved file.

**xmp**
    The XMP data to include in the saved file.

Saving sequences
~~~~~~~~~~~~~~~~

When calling :py:meth:`~PIL.Image.Image.save` to write a WebP file, by default
only the first frame of a multiframe image will be saved. If the ``save_all``
argument is present and true, or if ``append_images`` is not empty, all frames
will be saved, and the following options will also be available.

**append_images**
    A list of images to append as additional frames. Each of the
    images in the list can be single or multiframe images.

**duration**
    The display duration of each frame, in milliseconds. Pass a single
    integer for a constant duration, or a list or tuple to set the
    duration for each frame separately.

**loop**
    Number of times to repeat the animation. Defaults to [0 = infinite].

**background**
    Background color of the canvas, as an RGBA tuple with values in
    the range of (0-255).

**minimize_size**
    If true, minimize the output size (slow). Implicitly disables
    key-frame insertion.

**kmin, kmax**
    Minimum and maximum distance between consecutive key frames in
    the output. The library may insert some key frames as needed
    to satisfy this criteria. Note that these conditions should
    hold: kmax > kmin and kmin >= kmax / 2 + 1. Also, if kmax <= 0,
    then key-frame insertion is disabled; and if kmax == 1, then all
    frames will be key-frames (kmin value does not matter for these
    special cases).

**allow_mixed**
    If true, use mixed compression mode; the encoder heuristically
    chooses between lossy and lossless for each frame.

XBM
^^^

Pillow reads and writes X bitmap files (mode ``1``).

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**hotspot**
    The ``(x, y)`` hotspot of the bitmap, if the file defines one.

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**hotspot**
    An ``(x, y)`` tuple. If given, the hotspot is written to the file.

Read-only formats
-----------------

CUR
^^^

CUR is used to store cursors on Windows. The CUR decoder reads the largest
available cursor. Animated cursors are not supported.

DCX
^^^

DCX is a container file format for PCX files, defined by Intel. The DCX format
is commonly used in fax applications. The DCX decoder can read files containing
``1``, ``L``, ``P``, or ``RGB`` data.

When the file is opened, only the first image is read. You can use
:py:meth:`~PIL.Image.Image.seek` or :py:mod:`~PIL.ImageSequence` to read other images.

FITS
^^^^

.. versionadded:: 9.1.0

Pillow identifies and reads FITS files, commonly used for astronomy. Uncompressed and
GZIP_1 compressed images can be read.

FLI, FLC
^^^^^^^^

Pillow reads Autodesk FLI and FLC animations.

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**duration**
    The delay (in milliseconds) between each frame.

FPX
^^^

Pillow reads Kodak FlashPix files. Only the highest resolution image is read from the
file, and the viewing transform is not taken into account.

To enable FPX support, you must install :pypi:`olefile`.

.. note::

    To enable full FlashPix support, you need to build and install the IJG JPEG
    library before building the Python Imaging Library. See the distribution
    README for details.

FTEX
^^^^

.. versionadded:: 3.2.0

The FTEX decoder reads textures used for 3D objects in
Independence War 2: Edge Of Chaos. The plugin reads a single texture
per file, in the compressed and uncompressed formats.

GBR
^^^

The GBR decoder reads GIMP brush files, version 1 and 2.

.. _gbr-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**comment**
    The brush name.

**spacing**
    The spacing between the brushes, in pixels. Version 2 only.

GD
^^

Pillow reads uncompressed GD2 files. Note that you must use
:py:func:`PIL.GdImageFile.open` to read such a file.

.. _gd-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**transparency**
    Transparency color index. This key is omitted if the image is not
    transparent.

IMT
^^^

Pillow reads Image Tools images containing ``L`` data.

IPTC/NAA
^^^^^^^^

Pillow provides limited read support for IPTC/NAA newsphoto files.

MCIDAS
^^^^^^

Pillow identifies and reads 8-bit McIdas area files.

MIC
^^^

Pillow identifies and reads Microsoft Image Composer (MIC) files. When opened,
the first sprite in the file is loaded. You can use :py:meth:`~PIL.Image.Image.seek` and
:py:meth:`~PIL.Image.Image.tell` to read other sprites from the file.

Note that there may be an embedded gamma of 2.2 in MIC files.

To enable MIC support, you must install :pypi:`olefile`.

PCD
^^^

Pillow reads PhotoCD files containing ``RGB`` data. This only reads the 768x512
resolution image from the file. Higher resolutions are encoded in a proprietary
encoding.

PIXAR
^^^^^

Pillow provides limited support for PIXAR raster files. The library can
identify and read “dumped” RGB files.

The format code is ``PIXAR``.

PSD
^^^

Pillow identifies and reads PSD files written by Adobe Photoshop 2.5 and 3.0.

SUN
^^^

Pillow identifies and reads Sun raster files.

WAL
^^^

.. versionadded:: 1.1.4

Pillow reads Quake2 WAL texture files.

Note that this file format cannot be automatically identified, so you must use
the open function in the :py:mod:`~PIL.WalImageFile` module to read files in
this format.

By default, a Quake2 standard palette is attached to the texture. To override
the palette, use the :py:func:`PIL.Image.Image.putpalette()` method.

WMF, EMF
^^^^^^^^

Pillow can identify WMF and EMF files.

On Windows, it can read WMF and EMF files. By default, it will load the image
at 72 dpi. To load it at another resolution::

    from PIL import Image

    with Image.open("drawing.wmf") as im:
        im.load(dpi=144)

To add other read or write support, use
:py:func:`PIL.WmfImagePlugin.register_handler` to register a WMF and EMF
handler. ::

    from typing import IO

    from PIL import Image, ImageFile
    from PIL import WmfImagePlugin


    class WmfHandler(ImageFile.StubHandler):
        def open(self, im: ImageFile.StubImageFile) -> None:
            ...

        def load(self, im: ImageFile.StubImageFile) -> Image.Image:
            ...
            return image

        def save(self, im: Image.Image, fp: IO[bytes], filename: str) -> None:
            ...


    wmf_handler = WmfHandler()

    WmfImagePlugin.register_handler(wmf_handler)

    im = Image.open("sample.wmf")

XPM
^^^

Pillow reads X pixmap files as P mode images if there are 256 colors or less, and as
RGB images otherwise.

.. _xpm-opening:

Opening
~~~~~~~

The :py:meth:`~PIL.Image.open` method sets the following
:py:attr:`~PIL.Image.Image.info` properties:

**transparency**
    Transparency color index. This key is omitted if the image is not
    transparent.

XV thumbnails
^^^^^^^^^^^^^

Pillow can read XV thumbnail files.

Write-only formats
------------------

PALM
^^^^

Pillow provides write-only support for PALM pixmap files.

The format code is ``Palm``, the extension is ``.palm``.

``1``, ``L`` and ``P`` images can be saved.

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**bpp**
    For ``L`` images, the number of bits per pixel to write, either 1, 2 or 4. Shades
    in the image are adjusted to fit within this restriction. If omitted, the ``bpp``
    value from :py:attr:`~PIL.Image.Image.info` can be used instead, and only the
    lowest bits of each pixel are kept. If there is no ``bpp`` setting at all, ``L``
    mode images cannot be saved.

PDF
^^^

Pillow can write PDF (Acrobat) images. Such images are written as binary PDF 1.4
files. Different encoding methods are used, depending on the image mode.

* 1 mode images are saved using TIFF encoding, or JPEG encoding if libtiff support is
  unavailable
* L, RGB and CMYK mode images use JPEG encoding
* P mode images use HEX encoding
* LA and RGBA mode images use JPEG2000 encoding

.. _pdf-saving:

Saving
~~~~~~

The :py:meth:`~PIL.Image.Image.save` method can take the following keyword arguments:

**save_all**
    If a multiframe image is used, by default, only the first image will be saved.
    To save all frames, each frame to a separate page of the PDF, the ``save_all``
    parameter should be present and set to ``True`` or ``append_images`` should not be
    empty.

    .. versionadded:: 3.0.0

**append_images**
    A list of :py:class:`PIL.Image.Image` objects to append as additional pages. Each
    of the images in the list can be single or multiframe images.

    .. versionadded:: 4.2.0

**append**
    Set to True to append pages to an existing PDF file. If the file doesn't
    exist, an :py:exc:`OSError` will be raised.

    .. versionadded:: 5.1.0

**resolution**
    Image resolution in DPI. This, together with the number of pixels in the
    image, will determine the physical dimensions of the page that will be
    saved in the PDF.

**dpi**
    A tuple of ``(x_resolution, y_resolution)``, with inches as the resolution
    unit. If both the ``resolution`` parameter and the ``dpi`` parameter are
    present, ``resolution`` will be ignored.

**title**
    The document’s title. If not appending to an existing PDF file, this will
    default to the filename.

    .. versionadded:: 5.1.0

**author**
    The name of the person who created the document.

    .. versionadded:: 5.1.0

**subject**
    The subject of the document.

    .. versionadded:: 5.1.0

**keywords**
    Keywords associated with the document.

    .. versionadded:: 5.1.0

**creator**
    If the document was converted to PDF from another format, the name of the
    conforming product that created the original document from which it was
    converted.

    .. versionadded:: 5.1.0

**producer**
    If the document was converted to PDF from another format, the name of the
    conforming product that converted it to PDF.

    .. versionadded:: 5.1.0

**creationDate**
    The creation date of the document. If not appending to an existing PDF
    file, this will default to the current time.

    .. versionadded:: 5.3.0

**modDate**
    The modification date of the document. If not appending to an existing PDF
    file, this will default to the current time.

    .. versionadded:: 5.3.0

Identify-only formats
---------------------

BUFR
^^^^

.. versionadded:: 1.1.3

Pillow provides a stub driver for BUFR files.

To add read or write support to your application, use
:py:func:`PIL.BufrStubImagePlugin.register_handler`.

GRIB
^^^^

.. versionadded:: 1.1.5

Pillow provides a stub driver for GRIB files.

The driver requires the file to start with a GRIB header. If you have files
with embedded GRIB data, or files with multiple GRIB fields, your application
has to seek to the header before passing the file handle to Pillow.

To add read or write support to your application, use
:py:func:`PIL.GribStubImagePlugin.register_handler`.

HDF5
^^^^

.. versionadded:: 1.1.5

Pillow provides a stub driver for HDF5 files.

To add read or write support to your application, use
:py:func:`PIL.Hdf5StubImagePlugin.register_handler`.

MPEG
^^^^

Pillow identifies MPEG files.

---

### Handbook Index (`docs/handbook/index.rst`)

Handbook
========

.. toctree::
  :maxdepth: 2

  overview
  tutorial
  concepts
  appendices
  security

---

### Handbook Overview (`docs/handbook/overview.rst`)

Overview
========

The **Python Imaging Library** adds image processing capabilities to your
Python interpreter.

This library provides extensive file format support, an efficient internal
representation, and fairly powerful image processing capabilities.

The core image library is designed for fast access to data stored in a few
basic pixel formats. It should provide a solid foundation for a general image
processing tool.

Let’s look at a few possible uses of this library.

Image archives
--------------

The Python Imaging Library is ideal for image archival and batch processing
applications. You can use the library to create thumbnails, convert between
file formats, print images, etc.

The current version identifies and reads a large number of formats. Write
support is intentionally restricted to the most commonly used interchange and
presentation formats.

Image display
-------------

The current release includes Tk :py:class:`~PIL.ImageTk.PhotoImage` and
:py:class:`~PIL.ImageTk.BitmapImage` interfaces, as well as a :py:mod:`Windows
DIB interface <PIL.ImageWin>` that can be used with PythonWin and other
Windows-based toolkits. Many other GUI toolkits come with some kind of PIL
support.

For debugging, there’s also a :py:meth:`~PIL.Image.Image.show` method which saves an image to
disk, and calls an external display utility.

Image processing
----------------

The library contains basic image processing functionality, including point operations, filtering with a set of built-in convolution kernels, and colour space conversions.

The library also supports image resizing, rotation and arbitrary affine transforms.

There’s a histogram method allowing you to pull some statistics out of an image. This can be used for automatic contrast enhancement, and for global statistical analysis.

---

### Handbook Security (`docs/handbook/security.rst`)

Security
========

Pillow's primary attack surface is **parsing untrusted image data**. This page
documents the threat model for developers integrating Pillow into applications
that handle images from untrusted sources, along with recommended mitigations.

To report a vulnerability see :ref:`security-reporting`.

.. _security-threat-model:

Threat model (STRIDE)
---------------------

The analysis below follows the `STRIDE
<https://en.wikipedia.org/wiki/STRIDE_model>`_ framework and covers the
boundary between untrusted image input and the Pillow API.

.. code-block:: text

                    ┌──────────────────────────────────────────┐
   Untrusted zone   │             Pillow API                   │
   ─────────────    │                                          │
   Image files ────►│  Image.open()  ──►  Format plugins       │
   Byte streams     │  (40+ parsers)      (Python + C FFI)     │
   User metadata    │                                          │
                    │  ImageMath.unsafe_eval(expr)  ───────────┼──► Python eval()
                    │  ImageShow.show(image)  ─────────────────┼──► os.system / subprocess
                    │  EpsImagePlugin.open(eps)  ──────────────┼──► Ghostscript (gs)
                    └──────────────┬───────────────────────────┘
                                   │ C extensions:
                                   │  _imaging · _imagingft · _imagingcms
                                   │  _webp · _avif · _imagingtk
                                   │  _imagingmath · _imagingmorph
                                   ▼
                    ┌──────────────────────────────────────────┐
                    │  C libraries (bundled or system)         │
                    │  libjpeg · libpng · libtiff · libwebp    │
                    │  openjpeg · freetype · littlecms2        │
                    └──────────────────────────────────────────┘

Spoofing
^^^^^^^^

**S-1 — Format sniffing bypass**

``Image.open()`` detects format by magic bytes, not file extension or MIME
type. An attacker can name a file ``safe.png`` while its content is TIFF, JPEG
2000, or EPS, causing a different — potentially more dangerous — parser to run.

*Mitigations:* validate MIME type and magic bytes independently before calling
``Image.open()``; pass the ``formats`` argument with an allowlist of accepted
formats.

**S-2 — Plugin registry spoofing**

Pillow's format registry is a global mutable dictionary. A malicious package
installed in the same environment could register a replacement parser for a
well-known format.

*Mitigations:* use isolated virtual environments with pinned, hash-verified
dependencies; audit ``Image.registered_extensions()`` at startup.

Tampering
^^^^^^^^^

**T-1 — Malicious metadata propagation**

Pillow preserves EXIF, XMP, IPTC, ICC profiles, and comments when
round-tripping images. Applications that store or render metadata without
sanitisation are vulnerable to second-order injection (SQLi, XSS, command
injection).

*Mitigations:* treat all values from ``image.info``, ``image._getexif()``,
``image.getexif()``, and ``image.text`` as untrusted; sanitise before storing
or rendering; strip metadata when it is not required.

**T-2 — Covert data channel (steganography)**

Pillow does not remove hidden data (JPEG comments, PNG text chunks) when
re-saving. An attacker can embed data that survives the
encode-decode cycle invisibly.

*Mitigations:* to guarantee a clean output when saving, create a new image instance via
``image.copy()`` and delete the ``image.info`` contents.

**T-3 — Supply chain tampering**

Pre-compiled wheels bundle libjpeg-turbo, libpng, libtiff, libwebp, openjpeg,
freetype, littlecms2, and other libraries. A compromised PyPI release or build pipeline
could ship malicious binaries.

*Mitigations:* pin with hash verification
(``python3 -m pip install --require-hashes``); monitor `Pillow security advisories
<https://github.com/python-pillow/Pillow/security/advisories>`_; use
Dependabot or OSV-Scanner for bundled C library CVEs.

Repudiation
^^^^^^^^^^^

**R-1 — No structured audit trail**

Without application-level logging there is no record of which images were
opened, what formats were detected, or what operations were performed, making
forensic investigation harder after an incident.

*Mitigations:* log the filename/hash, detected format, and dimensions of every
image processed; log and alert on ``Image.DecompressionBombWarning``,
``Image.DecompressionBombError``, and ``PIL.UnidentifiedImageError``.

Information disclosure
^^^^^^^^^^^^^^^^^^^^^^

**I-1 — Metadata in saved images**

GPS coordinates, author names, software version strings, and ICC profiles can
be inadvertently included in output images served publicly.

*Mitigations:* explicitly strip EXIF and XMP on save (set ``exif=b""``,
``icc_profile=None``, omit ``pnginfo``); verify output with ``exiftool`` in CI.

**I-2 — Temporary file exposure**

Several code paths write pixel data to temporary files via
``tempfile.mkstemp()``. Exception paths can leave these files behind on shared
filesystems.

*Mitigations:* files are created with mode ``0o600``; mount ``/tmp`` as a
per-container ``tmpfs``; ensure ``try/finally`` cleanup is in place.

Denial of service
^^^^^^^^^^^^^^^^^

**D-1 — Decompression bomb**

A small compressed image can expand to gigabytes in memory.
:py:data:`PIL.Image.MAX_IMAGE_PIXELS` raises
``Image.DecompressionBombError`` at 2× the limit and
``Image.DecompressionBombWarning`` at 1×. PNG text chunks are
separately capped by ``PngImagePlugin.MAX_TEXT_CHUNK`` and
``MAX_TEXT_MEMORY``. Check the values in your installed Pillow version at
runtime or in the reference/source for the current defaults.

*Mitigations:* **never** set ``Image.MAX_IMAGE_PIXELS = None`` in production;
treat ``Image.DecompressionBombWarning`` as an error; set OS/container memory limits
per worker.

**D-2 — CPU exhaustion**

Large-but-legal images (within ``MAX_IMAGE_PIXELS``) can still saturate CPU
through high-quality resampling, convolution filters, or complex draw
operations.

*Mitigations:* apply per-request CPU time limits; set a practical dimension
ceiling below ``MAX_IMAGE_PIXELS``; rate-limit processing requests.

**D-3 — Algorithmic complexity in parsers**

Formats such as TIFF (nested IFD chains), animated GIF/WebP (many frames), and
PNG (many text chunks) can exhaust CPU or memory before pixel data is decoded.

*Mitigations:* restrict accepted formats to the minimum required; enforce a
file-size limit before passing data to Pillow; use per-request timeouts.

Elevation of privilege
^^^^^^^^^^^^^^^^^^^^^^

**E-1 — C extension memory corruption (RCE)**

Pillow's ~87 C source files and its bundled C libraries process
attacker-controlled bytes. Historical CVEs include buffer overflows, integer
overflows, and use-after-free vulnerabilities that allow arbitrary code
execution.

*Mitigations:* keep Pillow and all C libraries up to date; compile with
hardening flags (ASLR, stack canaries, PIE, ``_FORTIFY_SOURCE=2``); run image
processing in a sandboxed subprocess (seccomp-bpf, AppArmor, or a restricted
container).

**E-2 — Ghostscript exploitation via EPS (RCE)**

Opening an EPS file invokes the system Ghostscript binary (``gs``) via
``subprocess``. Ghostscript has a long history of sandbox-escape CVEs
permitting arbitrary code execution from malicious PostScript.

*Mitigations:* **block EPS files** at the application input layer before
passing files to Pillow; if EPS must be supported, run Ghostscript in a fully
isolated sandbox with no network and no sensitive mounts. Pillow does not
provide a stable public API for unregistering individual format plugins, so do
not rely on mutating internal registries such as ``Image.OPEN`` as a security
control.


**E-3 — ImageMath.unsafe_eval() code injection**

:py:meth:`~PIL.ImageMath.unsafe_eval` calls Python's built-in ``eval()`` with
only a minimal ``__builtins__`` restriction, which can be bypassed via
introspection. Any user-controlled string passed to this function results in
arbitrary code execution.

*Mitigations:* **never** pass user-controlled strings to
``ImageMath.unsafe_eval()``; use :py:meth:`~PIL.ImageMath.lambda_eval` instead,
which accepts a Python callable and never calls ``eval``.

**E-4 — Font path traversal via ImageFont**

``ImageFont.truetype(font, size)`` passes the filename to the FreeType C
library. If font paths are constructed from user input without
canonicalisation, an attacker may supply a path like
``../../../../etc/passwd``.

*Mitigations:* never construct font paths from user input; if font selection
must be user-driven, resolve names against an explicit allowlist of
pre-validated absolute paths.

.. _security-recommendations:

Recommendations
---------------

The following mitigations are listed in priority order.

1. **Sandbox image processing** — run Pillow workers in a seccomp/AppArmor
   restricted subprocess, isolated from the main application process.
2. **Block or sandbox EPS** — reject EPS at the application boundary, or run
   Ghostscript in an isolated container.
3. **Never use** ``ImageMath.unsafe_eval()`` **with user input** — migrate all
   callers to :py:meth:`~PIL.ImageMath.lambda_eval`.
4. **Keep all dependencies current** — Pillow and its C library dependencies
   (including libjpeg, libpng, libtiff, libwebp, openjpeg, freetype,
   littlecms2, Ghostscript, and others). Subscribe to `Pillow security
   advisories <https://github.com/python-pillow/Pillow/security/advisories>`_.
5. **Enforce** ``MAX_IMAGE_PIXELS`` — never set it to ``None``; treat
   ``Image.DecompressionBombWarning`` as an error.
6. **Allowlist image formats** — restrict accepted formats when opening
   images, for example with ``Image.open(..., formats=...)``, and isolate
   installs/environments if you need to minimise supported formats.
7. **Strip metadata on output** — never pass through EXIF/XMP/ICC from user
   uploads to publicly served images.
8. **Sanitise all metadata** returned by Pillow before using it downstream.
9. **Pin dependencies with hash verification** — use
   ``pip install --require-hashes`` and lockfiles.
10. **Log and alert** on ``Image.DecompressionBombWarning``,
    ``Image.DecompressionBombError``, ``PIL.UnidentifiedImageError``,
    and all exceptions from ``Image.open()``.

.. _security-reporting:

Reporting a vulnerability
-------------------------

To report sensitive vulnerability information, report it `privately on GitHub
<https://github.com/python-pillow/Pillow/security/advisories/new>`_.

If you cannot use GitHub, use the `Tidelift security contact
<https://tidelift.com/docs/security>`_. Tidelift will coordinate the fix and
disclosure.

**Do not report sensitive vulnerability information in public.**

What to include and how to structure a vulnerability report
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* For the initial report and follow-up communications, avoid overly
  long, verbose, or excessive structure (such as headers or tables).
  Reports should be a few sentences describing the vulnerability.
  Ideally include a proof-of-concept script that reproduces the issue
  and provides a clear indication of whether the vulnerability is still
  present (such as exiting with ``1`` if vulnerable and ``0`` if not
  vulnerable).

* When reporting large numbers or "batches" of vulnerabilities, or
  searching for potential vulnerabilities using an LLM, you as a
  reporter must verify the factual validity (such as whether APIs have
  been hallucinated) of the content in all reports prior to submission.

* Check published `security advisories
  <https://github.com/python-pillow/Pillow/security/advisories>`__ and the
  `issue tracker <https://github.com/python-pillow/Pillow/issues>`__ for an
  existing report before submitting. Advisories still under triage are not
  public, so not every report will be visible to you.

* Validate the issue against the :ref:`threat model <security-threat-model>`
  and state which category it falls under. Behaviour already documented
  as an accepted risk is not a vulnerability and will be closed.

* When submitting a batch, deduplicate within it, report one issue per
  distinct defect rather than one per trigger, and note any relationships
  between your reports. Large batches may be triaged as a batch rather
  than individually, and may take longer to process.

* Ideally, include a minimal patch with the mitigation for the report.

* Always include the Pillow versions that were tested, and indicate which
  were found to be vulnerable. For issues in C code, also include the
  versions of the relevant bundled libraries, such as libjpeg, libtiff or
  libwebp.

* Prefer a script that generates any input files over attaching them. If a
  file must be attached, use the smallest one that reproduces the issue.

* Proof-of-concept scripts longer than a few lines should be wrapped with a
  collapsed section using ``<details></details>`` for better readability.

* Ensure that your issue is reproducible in ``main``. We only
  support the latest version. The one exception -- if your issue is
  exploitable in the latest public release, but not in ``main``, and the
  pull request does not mention a security implication this may be an
  unknown security issue that was inadvertently fixed.

* Demonstrating a memory overflow is enough. Do not weaponize
  the reproducer to do remote code execution.

* Do not report unexpected Python exceptions as a DoS or a
  memory safety bug.  An issue that raises a Python exception in a
  library is unlikely to be considered a security issue. This may or
  may not be an ordinary bug depending on the context.

* Reports that do not contain a potential security vulnerability (such as
  spam or requesting compliance or due-diligence work) will be discarded
  without a reply.

---

### Handbook Text Anchors (`docs/handbook/text-anchors.rst`)

.. _text-anchors:

Text anchors
============

The ``anchor`` parameter determines the alignment of drawn text relative to the ``xy`` parameter.
The default alignment is top left, specifically ``la`` (left-ascender) for horizontal text
and ``lt`` (left-top) for vertical text.

This parameter is only supported by OpenType/TrueType fonts.
Other fonts may ignore the parameter and use the default (top left) alignment.

Specifying an anchor
^^^^^^^^^^^^^^^^^^^^

An anchor is specified with a two-character string. The first character is the
horizontal alignment, the second character is the vertical alignment.
For example, the default value of ``la`` for horizontal text means left-ascender
aligned text.

When drawing text with :py:meth:`PIL.ImageDraw.ImageDraw.text` with a specific anchor,
the text will be placed such that the specified anchor point is at the ``xy`` coordinates.

For example, in the following image, the text is ``ms`` (middle-baseline) aligned, with
``xy`` at the intersection of the two lines:

.. image:: ../../Tests/images/test_anchor_quick_ms.png
  :alt: ms (middle-baseline) aligned text.
  :align: left

::

    from PIL import Image, ImageDraw, ImageFont

    font = ImageFont.truetype("Tests/fonts/NotoSans-Regular.ttf", 48)
    im = Image.new("RGB", (200, 200), "white")
    d = ImageDraw.Draw(im)
    d.line(((0, 100), (200, 100)), "gray")
    d.line(((100, 0), (100, 200)), "gray")
    d.text((100, 100), "Quick", fill="black", anchor="ms", font=font)

.. container:: clearer

    |

.. only: comment
    The container above prevents the image alignment from affecting the following text.

Quick reference
^^^^^^^^^^^^^^^

.. image:: ../resources/anchor_horizontal.svg
  :alt: Horizontal text
  :align: center

.. image:: ../resources/anchor_vertical.svg
  :alt: Vertical text
  :align: center

Horizontal anchor alignment
^^^^^^^^^^^^^^^^^^^^^^^^^^^

``l`` --- left
    Anchor is to the left of the text.

    For *horizontal* text this is the origin of the first glyph, as shown in the `FreeType tutorial`_.

``m`` --- middle
    Anchor is horizontally centered with the text.

    For *vertical* text it is recommended to use ``s`` (baseline) alignment instead,
    as it does not change based on the specific glyphs of the given text.

``r`` --- right
    Anchor is to the right of the text.

    For *horizontal* text this is the advanced origin of the last glyph, as shown in the `FreeType tutorial`_.

``s`` --- baseline *(vertical text only)*
    Anchor is at the baseline (middle) of the text. The exact alignment depends on the font.

    For *vertical* text this is the recommended alignment,
    as it does not change based on the specific glyphs of the given text
    (see image for vertical text above).

Vertical anchor alignment
^^^^^^^^^^^^^^^^^^^^^^^^^

``a`` --- ascender / top *(horizontal text only)*
    Anchor is at the ascender line (top) of the first line of text, as defined by the font.

    See `Font metrics on Wikipedia`_ for more information.

``t`` --- top *(single-line text only)*
    Anchor is at the top of the text.

    For *vertical* text this is the origin of the first glyph, as shown in the `FreeType tutorial`_.

    For *horizontal* text it is recommended to use ``a`` (ascender) alignment instead,
    as it does not change based on the specific glyphs of the given text.

``m`` --- middle
    Anchor is vertically centered with the text.

    For *horizontal* text this is the midpoint of the first ascender line and the last descender line.

``s`` --- baseline *(horizontal text only)*
    Anchor is at the baseline (bottom) of the first line of text, only descenders extend below the anchor.

    See `Font metrics on Wikipedia`_ for more information.

``b`` --- bottom *(single-line text only)*
    Anchor is at the bottom of the text.

    For *vertical* text this is the advanced origin of the last glyph, as shown in the `FreeType tutorial`_.

    For *horizontal* text it is recommended to use ``d`` (descender) alignment instead,
    as it does not change based on the specific glyphs of the given text.

``d`` --- descender / bottom *(horizontal text only)*
    Anchor is at the descender line (bottom) of the last line of text, as defined by the font.

    See `Font metrics on Wikipedia`_ for more information.

Examples
^^^^^^^^

The following image shows several examples of anchors for horizontal text.
In each section the ``xy`` parameter was set to the center shown by the intersection
of the two lines.

.. comment: Image generated with ../example/anchors.py

.. image:: ../example/anchors.webp
    :alt: Text anchor examples
    :align: center

.. _Font metrics on Wikipedia: https://en.wikipedia.org/wiki/Typeface#Font_metrics
.. _FreeType tutorial: https://freetype.org/freetype2/docs/tutorial/step2.html

---

### Handbook Third Party Plugins (`docs/handbook/third-party-plugins.rst`)

Third-party plugins
===================

Pillow uses a plugin model which allows users to add their own
decoders and encoders to the library, without any changes to the library
itself.

Here is a list of PyPI projects that offer additional plugins:

* :pypi:`amigainfo`: Adds support for Amiga Workbench .info icon files.
* :pypi:`amos-abk`: AMOS BASIC sprite and image banks.
* :pypi:`DjvuRleImagePlugin`: Plugin for the DjVu RLE image format as defined in the DjVuLibre docs.
* :pypi:`heif-image-plugin`: Simple HEIF/HEIC images plugin, based on the pyheif library.
* :pypi:`jxlpy`: Introduces reading and writing support for JPEG XL.
* :pypi:`pillow-degas`: Adds reading Atari ST Degas image files.
* :pypi:`pillow-heif`: Python bindings to libheif for working with HEIF images.
* :pypi:`pillow-jpls`: Plugin for the JPEG-LS codec, based on the Charls JPEG-LS implementation. Python bindings implemented using pybind11.
* :pypi:`pillow-jxl-plugin`: Plugin for JPEG-XL, using Rust for bindings.
* :pypi:`pillow-lunasvg`: SVG read support based on the LunaSVG C++ library. Wheels for Linux, macOS and Windows, no system libraries needed.
* :pypi:`pillow-mbm`: Adds support for KSP's proprietary MBM texture format.
* :pypi:`pillow-netpbm`: Adds .pam support, and loads images using `Netpbm <https://en.wikipedia.org/wiki/Netpbm>`__'s converter collection.
* :pypi:`pillow-svg`: Implements basic SVG read support. Supports basic paths, shapes, and text.
* :pypi:`pillow-wmf`: Cross platform support for Windows MetaFiles.
* :pypi:`pillow-zx-spectrum`: Open loading SCREEN$ from ZX Spectrum tapes, disks and memory snapshots.
* :pypi:`raw-pillow-opener`: Simple camera raw opener, based on the rawpy library.

---

### Handbook Tutorial (`docs/handbook/tutorial.rst`)

Tutorial
========

Using the Image class
---------------------

The most important class in the Python Imaging Library is the
:py:class:`~PIL.Image.Image` class, defined in the module with the same name.
You can create instances of this class in several ways; either by loading
images from files, processing other images, or creating images from scratch.

To load an image from a file, use the :py:func:`~PIL.Image.open` function
in the :py:mod:`~PIL.Image` module::

    >>> from PIL import Image
    >>> im = Image.open("hopper.ppm")

If successful, this function returns an :py:class:`~PIL.Image.Image` object.
You can now use instance attributes to examine the file contents::

    >>> print(im.format, im.size, im.mode)
    PPM (512, 512) RGB

The :py:attr:`~PIL.Image.Image.format` attribute identifies the source of an
image. If the image was not read from a file, it is set to None. The size
attribute is a 2-tuple containing width and height (in pixels). The
:py:attr:`~PIL.Image.Image.mode` attribute defines the number and names of the
bands in the image, and also the pixel type and depth. Common modes are “L”
(luminance) for grayscale images, “RGB” for true color images, and “CMYK” for
pre-press images.

If the file cannot be opened, an :py:exc:`OSError` exception is raised.

Once you have an instance of the :py:class:`~PIL.Image.Image` class, you can use
the methods defined by this class to process and manipulate the image. For
example, let’s display the image we just loaded::

    >>> im.show()

.. image:: show_hopper.webp
    :align: center

.. note::

    The standard version of :py:meth:`~PIL.Image.Image.show` is not very
    efficient, since it saves the image to a temporary file and calls a utility
    to display the image. If you don’t have an appropriate utility installed,
    it won’t even work. When it does work though, it is very handy for
    debugging and tests.

The following sections provide an overview of the different functions provided in this library.

Reading and writing images
--------------------------

The Python Imaging Library supports a wide variety of image file formats. To
read files from disk, use the :py:func:`~PIL.Image.open` function in the
:py:mod:`~PIL.Image` module. You don’t have to know the file format to open a
file. The library automatically determines the format based on the contents of
the file.

To save a file, use the :py:meth:`~PIL.Image.Image.save` method of the
:py:class:`~PIL.Image.Image` class. When saving files, the name becomes
important. Unless you specify the format, the library uses the filename
extension to discover which file storage format to use.

Convert files to JPEG
^^^^^^^^^^^^^^^^^^^^^

::

    import os, sys
    from PIL import Image

    for infile in sys.argv[1:]:
        f, e = os.path.splitext(infile)
        outfile = f + ".jpg"
        if infile != outfile:
            try:
                with Image.open(infile) as im:
                    im.save(outfile)
            except OSError:
                print("cannot convert", infile)

.. image:: ../../Tests/images/hopper.jpg
    :align: center

A second argument can be supplied to the :py:meth:`~PIL.Image.Image.save`
method which explicitly specifies a file format. If you use a non-standard
extension, you must always specify the format this way:

Create JPEG thumbnails
^^^^^^^^^^^^^^^^^^^^^^

::

    import os, sys
    from PIL import Image

    size = (128, 128)

    for infile in sys.argv[1:]:
        outfile = os.path.splitext(infile)[0] + ".thumbnail"
        if infile != outfile:
            try:
                with Image.open(infile) as im:
                    im.thumbnail(size)
                    im.save(outfile, "JPEG")
            except OSError:
                print("cannot create thumbnail for", infile)

.. image:: thumbnail_hopper.jpg
    :align: center

It is important to note that the library doesn’t decode or load the raster data
unless it really has to. When you open a file, the file header is read to
determine the file format and extract things like mode, size, and other
properties required to decode the file, but the rest of the file is not
processed until later.

This means that opening an image file is a fast operation, which is independent
of the file size and compression type. Here’s a simple script to quickly
identify a set of image files:

Identify image files
^^^^^^^^^^^^^^^^^^^^

::

    import sys
    from PIL import Image

    for infile in sys.argv[1:]:
        try:
            with Image.open(infile) as im:
                print(infile, im.format, f"{im.size}x{im.mode}")
        except OSError:
            pass

Cutting, pasting, and merging images
------------------------------------

The :py:class:`~PIL.Image.Image` class contains methods allowing you to
manipulate regions within an image. To extract a sub-rectangle from an image,
use the :py:meth:`~PIL.Image.Image.crop` method.

Copying a subrectangle from an image
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    box = (0, 0, 64, 64)
    region = im.crop(box)

The region is defined by a 4-tuple, where coordinates are (left, upper, right,
lower). The Python Imaging Library uses a coordinate system with (0, 0) in the
upper left corner. Also note that coordinates refer to positions between the
pixels, so the region in the above example is exactly 64x64 pixels.

The region could now be processed in a certain manner and pasted back.

.. image:: cropped_hopper.webp
    :align: center

Processing a subrectangle, and pasting it back
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    region = region.transpose(Image.Transpose.ROTATE_180)
    im.paste(region, box)

When pasting regions back, the size of the region must match the given region
exactly. In addition, the region cannot extend outside the image. However, the
modes of the original image and the region do not need to match. If they don’t,
the region is automatically converted before being pasted (see the section on
:ref:`color-transforms` below for details).

.. image:: pasted_hopper.webp
    :align: center

Here’s an additional example:

Rolling an image
^^^^^^^^^^^^^^^^

::

    def roll(im: Image.Image, delta: int) -> Image.Image:
        """Roll an image sideways."""
        xsize, ysize = im.size

        delta = delta % xsize
        if delta == 0:
            return im

        part1 = im.crop((0, 0, delta, ysize))
        part2 = im.crop((delta, 0, xsize, ysize))
        im.paste(part1, (xsize - delta, 0, xsize, ysize))
        im.paste(part2, (0, 0, xsize - delta, ysize))

        return im

.. image:: rolled_hopper.webp
    :align: center

Or if you would like to merge two images into a wider image:

Merging images
^^^^^^^^^^^^^^

::

    def merge(im1: Image.Image, im2: Image.Image) -> Image.Image:
        w = im1.size[0] + im2.size[0]
        h = max(im1.size[1], im2.size[1])
        im = Image.new("RGBA", (w, h))

        im.paste(im1)
        im.paste(im2, (im1.size[0], 0))

        return im

.. image:: merged_hopper.webp
    :align: center

For more advanced tricks, the paste method can also take a transparency mask as
an optional argument. In this mask, the value 255 indicates that the pasted
image is opaque in that position (that is, the pasted image should be used as
is). The value 0 means that the pasted image is completely transparent. Values
in-between indicate different levels of transparency. For example, pasting an
RGBA image and also using it as the mask would paste the opaque portion
of the image but not its transparent background.

The Python Imaging Library also allows you to work with the individual bands of
a multi-band image, such as an RGB image. The split method creates a set of new
images, each containing one band from the original multi-band image. The merge
function takes a mode and a tuple of images, and combines them into a new
image. The following sample swaps the three bands of an RGB image:

Splitting and merging bands
^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    r, g, b = im.split()
    im = Image.merge("RGB", (b, g, r))

Note that for a single-band image, :py:meth:`~PIL.Image.Image.split` returns
the image itself. To work with individual color bands, you may want to convert
the image to “RGB” first.

.. image:: rebanded_hopper.webp
    :align: center

Geometrical transforms
----------------------

The :py:class:`PIL.Image.Image` class contains methods to
:py:meth:`~PIL.Image.Image.resize` and :py:meth:`~PIL.Image.Image.rotate` an
image. The former takes a tuple giving the new size, the latter the angle in
degrees counterclockwise.

Simple geometry transforms
^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    out = im.resize((128, 128))
    out = im.rotate(45) # degrees counterclockwise

.. image:: rotated_hopper_90.webp
    :align: center

To rotate the image in 90 degree steps, you can either use the
:py:meth:`~PIL.Image.Image.rotate` method or the
:py:meth:`~PIL.Image.Image.transpose` method. The latter can also be used to
flip an image around its horizontal or vertical axis.

Transposing an image
^^^^^^^^^^^^^^^^^^^^

::

    out = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT)

.. image:: flip_left_right_hopper.webp
    :align: center

::

    out = im.transpose(Image.Transpose.FLIP_TOP_BOTTOM)

.. image:: flip_top_bottom_hopper.webp
    :align: center

::

    out = im.transpose(Image.Transpose.ROTATE_90)

.. image:: rotated_hopper_90.webp
    :align: center

::

    out = im.transpose(Image.Transpose.ROTATE_180)

.. image:: rotated_hopper_180.webp
    :align: center

::

    out = im.transpose(Image.Transpose.ROTATE_270)

.. image:: rotated_hopper_270.webp
    :align: center

``transpose(ROTATE)`` operations can also be performed identically with
:py:meth:`~PIL.Image.Image.rotate` operations, provided the ``expand`` flag is
true, to provide for the same changes to the image's size.

A more general form of image transformations can be carried out via the
:py:meth:`~PIL.Image.Image.transform` method.

Relative resizing
^^^^^^^^^^^^^^^^^

Instead of calculating the size of the new image when resizing, you can also
choose to resize relative to a given size.

::

    from PIL import Image, ImageOps
    size = (100, 150)
    with Image.open("hopper.webp") as im:
        ImageOps.contain(im, size).save("imageops_contain.webp")
        ImageOps.cover(im, size).save("imageops_cover.webp")
        ImageOps.fit(im, size).save("imageops_fit.webp")
        ImageOps.pad(im, size, color="#f00").save("imageops_pad.webp")

        # thumbnail() can also be used,
        # but will modify the image object in place
        im.thumbnail(size)
        im.save("image_thumbnail.webp")

+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|                | :py:meth:`~PIL.Image.Image.thumbnail`      | :py:meth:`~PIL.ImageOps.contain`            | :py:meth:`~PIL.ImageOps.cover`            | :py:meth:`~PIL.ImageOps.fit`            | :py:meth:`~PIL.ImageOps.pad`            |
+================+============================================+=============================================+===========================================+=========================================+=========================================+
|Given size      | ``(100, 150)``                             | ``(100, 150)``                              | ``(100, 150)``                            | ``(100, 150)``                          | ``(100, 150)``                          |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|Resulting image | .. image:: ../example/image_thumbnail.webp | .. image:: ../example/imageops_contain.webp | .. image:: ../example/imageops_cover.webp | .. image:: ../example/imageops_fit.webp | .. image:: ../example/imageops_pad.webp |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|Resulting size  | ``100×100``                                | ``100×100``                                 | ``150×150``                               | ``100×150``                             | ``100×150``                             |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+

.. _color-transforms:

Color transforms
----------------

The Python Imaging Library allows you to convert images between different pixel
representations using the :py:meth:`~PIL.Image.Image.convert` method.

Converting between modes
^^^^^^^^^^^^^^^^^^^^^^^^

::

    from PIL import Image

    with Image.open("hopper.ppm") as im:
        im = im.convert("L")

The library supports transformations between each supported mode and the “L”
and “RGB” modes. To convert between other modes, you may have to use an
intermediate image (typically an “RGB” image).

Image enhancement
-----------------

The Python Imaging Library provides a number of methods and modules that can be
used to enhance images.

Filters
^^^^^^^

The :py:mod:`~PIL.ImageFilter` module contains a number of pre-defined
enhancement filters that can be used with the
:py:meth:`~PIL.Image.Image.filter` method.

Applying filters
~~~~~~~~~~~~~~~~

::

    from PIL import ImageFilter
    out = im.filter(ImageFilter.DETAIL)

.. image:: enhanced_hopper.webp
    :align: center

Point operations
^^^^^^^^^^^^^^^^

The :py:meth:`~PIL.Image.Image.point` method can be used to translate the pixel
values of an image (e.g. image contrast manipulation). In most cases, a
function object expecting one argument can be passed to this method. Each
pixel is processed according to that function:

Applying point transforms
~~~~~~~~~~~~~~~~~~~~~~~~~

::

    # multiply each pixel by 20
    out = im.point(lambda i: i * 20)

.. image:: transformed_hopper.webp
    :align: center

Using the above technique, you can quickly apply any simple expression to an
image. You can also combine the :py:meth:`~PIL.Image.Image.point` and
:py:meth:`~PIL.Image.Image.paste` methods to selectively modify an image:

Processing individual bands
~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    # split the image into individual bands
    source = im.split()

    R, G, B = 0, 1, 2

    # select regions where red is less than 100
    mask = source[R].point(lambda i: i < 100 and 255)

    # process the green band
    out = source[G].point(lambda i: i * 0.7)

    # paste the processed band back, but only where red was < 100
    source[G].paste(out, None, mask)

    # build a new multiband image
    im = Image.merge(im.mode, source)

Note the syntax used to create the mask::

    imout = im.point(lambda i: expression and 255)

.. image:: masked_hopper.webp
    :align: center

Python only evaluates the portion of a logical expression as is necessary to
determine the outcome, and returns the last value examined as the result of the
expression. So if the expression above is false (0), Python does not look at
the second operand, and thus returns 0. Otherwise, it returns 255.

Enhancement
^^^^^^^^^^^

For more advanced image enhancement, you can use the classes in the
:py:mod:`~PIL.ImageEnhance` module. Once created from an image, an enhancement
object can be used to quickly try out different settings.

You can adjust contrast, brightness, color balance and sharpness in this way.

Enhancing images
~~~~~~~~~~~~~~~~

::

    from PIL import ImageEnhance

    enh = ImageEnhance.Contrast(im)
    enh.enhance(1.3).show("30% more contrast")


.. image:: contrasted_hopper.jpg
    :align: center

Image sequences
---------------

The Python Imaging Library contains some basic support for image sequences
(also called animation formats). Supported sequence formats include FLI/FLC,
GIF, and a few experimental formats. TIFF files can also contain more than one
frame.

When you open a sequence file, PIL automatically loads the first frame in the
sequence. You can use the seek and tell methods to move between different
frames:

Reading sequences
^^^^^^^^^^^^^^^^^

::

    from PIL import Image

    with Image.open("animation.gif") as im:
        im.seek(1)  # skip to the second frame

        try:
            while 1:
                im.seek(im.tell() + 1)
                # do something to im
        except EOFError:
            pass  # end of sequence

As seen in this example, you’ll get an :py:exc:`EOFError` exception when the
sequence ends.

Writing sequences
^^^^^^^^^^^^^^^^^

You can create animated GIFs with Pillow, e.g.

::

    from PIL import Image

    # List of image filenames
    image_filenames = [
        "hopper.jpg",
        "rotated_hopper_270.jpg",
        "rotated_hopper_180.jpg",
        "rotated_hopper_90.jpg",
    ]

    # Open images and create a list
    images = [Image.open(filename) for filename in image_filenames]

    # Save the images as an animated GIF
    images[0].save(
        "animated_hopper.gif",
        append_images=images[1:],
        duration=500,  # duration of each frame in milliseconds
        loop=0,  # loop forever
    )


.. image:: animated_hopper.gif
    :align: center

The following class lets you use the for-statement to loop over the sequence:

Using the :py:class:`~PIL.ImageSequence.Iterator` class
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    from PIL import ImageSequence
    for frame in ImageSequence.Iterator(im):
        # ...do something to frame...


PostScript printing
-------------------

The Python Imaging Library includes functions to print images, text and
graphics on PostScript printers. Here’s a simple example:

Drawing PostScript
^^^^^^^^^^^^^^^^^^

::

    from PIL import Image, PSDraw
    import os

    # Define the PostScript file
    ps_file = open("hopper.ps", "wb")

    # Create a PSDraw object
    ps = PSDraw.PSDraw(ps_file)

    # Start the document
    ps.begin_document()

    # Set the text to be drawn
    text = "Hopper"

    # Define the PostScript font
    font_name = "Helvetica-Narrow-Bold"
    font_size = 36

    # Calculate text size (approximation as PSDraw doesn't provide direct method)
    # Assuming average character width as 0.6 of the font size
    text_width = len(text) * font_size * 0.6
    text_height = font_size

    # Set the position (top-center)
    page_width, page_height = 595, 842  # A4 size in points
    text_x = (page_width - text_width) // 2
    text_y = page_height - text_height - 50  # Distance from the top of the page

    # Load the image
    image_path = "hopper.ppm"  # Update this with your image path
    with Image.open(image_path) as im:
        # Resize the image if it's too large
        im.thumbnail((page_width - 100, page_height // 2))

        # Define the box where the image will be placed
        img_x = (page_width - im.width) // 2
        img_y = text_y + text_height - 200  # 200 points below the text

        # Draw the image (75 dpi)
        ps.image((img_x, img_y, img_x + im.width, img_y + im.height), im, 75)

    # Draw the text
    ps.setfont(font_name, font_size)
    ps.text((text_x, text_y), text)

    # End the document
    ps.end_document()
    ps_file.close()

.. image:: hopper_ps.webp

.. note::

    PostScript converted to PDF for display purposes

More on reading images
----------------------

As described earlier, the :py:func:`~PIL.Image.open` function of the
:py:mod:`~PIL.Image` module is used to open an image file. In most cases, you
simply pass it the filename as an argument. ``Image.open()`` can be used as a
context manager::

    from PIL import Image
    with Image.open("hopper.ppm") as im:
        ...

If everything goes well, the result is an :py:class:`PIL.Image.Image` object.
Otherwise, an :exc:`OSError` exception is raised.

You can use a file-like object instead of the filename. The object must
implement ``file.read``, ``file.seek`` and ``file.tell`` methods,
and be opened in binary mode.

Reading from an open file
^^^^^^^^^^^^^^^^^^^^^^^^^

::

    from PIL import Image

    with open("hopper.ppm", "rb") as fp:
        im = Image.open(fp)

To read an image from binary data, use the :py:class:`~io.BytesIO`
class:

Reading from binary data
^^^^^^^^^^^^^^^^^^^^^^^^

::

    from PIL import Image
    import io

    im = Image.open(io.BytesIO(buffer))

Note that the library rewinds the file (using ``seek(0)``) before reading the
image header. In addition, seek will also be used when the image data is read
(by the load method). If the image file is embedded in a larger file, such as a
tar file, you can use the :py:class:`~PIL.ContainerIO` or
:py:class:`~PIL.TarIO` modules to access it.

Reading from URL
^^^^^^^^^^^^^^^^

::

    from PIL import Image
    from urllib.request import urlopen
    url = "https://python-pillow.org/assets/images/pillow-logo.png"
    img = Image.open(urlopen(url))


Reading from a tar archive
^^^^^^^^^^^^^^^^^^^^^^^^^^

::

    from PIL import Image, TarIO

    fp = TarIO.TarIO("hopper.tar", "hopper.jpg")
    im = Image.open(fp)


Batch processing
^^^^^^^^^^^^^^^^

Operations can be applied to multiple image files. For example, all PNG images
in the current directory can be saved as JPEGs at reduced quality.

::

    import glob
    from PIL import Image

    def compress_image(source_path: str, dest_path: str) -> None:
        with Image.open(source_path) as img:
            if img.mode != "RGB":
                img = img.convert("RGB")
            img.save(dest_path, "JPEG", optimize=True, quality=80)


    paths = glob.glob("*.png")
    for path in paths:
        compress_image(path, path[:-4] + ".jpg")

Since images can also be opened from a ``Path`` from the ``pathlib`` module,
the example could be modified to use ``pathlib`` instead of the ``glob``
module.

::

    from pathlib import Path

    paths = Path(".").glob("*.png")
    for path in paths:
        compress_image(path, path.stem + ".jpg")


Controlling the decoder
-----------------------

Some decoders allow you to manipulate the image while reading it from a file.
This can often be used to speed up decoding when creating thumbnails (when
speed is usually more important than quality) and printing to a monochrome
laser printer (when only a grayscale version of the image is needed).

The :py:meth:`~PIL.Image.Image.draft` method manipulates an opened but not yet
loaded image so it as closely as possible matches the given mode and size. This
is done by reconfiguring the image decoder.

Reading in draft mode
^^^^^^^^^^^^^^^^^^^^^

This is only available for JPEG and MPO files.

::

    from PIL import Image

    with Image.open(file) as im:
        print("original =", im.mode, im.size)

        im.draft("L", (100, 100))
        print("draft =", im.mode, im.size)

This prints something like::

    original = RGB (512, 512)
    draft = L (128, 128)

Note that the resulting image may not exactly match the requested mode and
size. To make sure that the image is not larger than the given size, use the
thumbnail method instead.

---

### Handbook Writing Your Own Image Plugin (`docs/handbook/writing-your-own-image-plugin.rst`)

.. _image-plugins:

Writing your own image plugin
=============================

Pillow uses a plugin model which allows you to add your own
decoders and encoders to the library, without any changes to the library
itself. Such plugins usually have names like :file:`XxxImagePlugin.py`,
where ``Xxx`` is a unique format name (usually an abbreviation).

.. warning:: Pillow >= 2.1.0 no longer automatically imports any file
             in the Python path with a name ending in
             :file:`ImagePlugin.py`.  You will need to import your
             image plugin manually.

Pillow decodes files in two stages:

1. It loops over the available image plugins in the loaded order, and
   calls the plugin's ``_accept`` function with the first 16 bytes of
   the file. If the ``_accept`` function returns true, the plugin's
   ``_open`` method is called to set up the image metadata and image
   tiles. The ``_open`` method is not for decoding the actual image
   data.
2. When the image data is requested, the ``ImageFile.load`` method is
   called, which sets up a decoder for each tile and feeds the data to
   it.

An image plugin should contain a format handler derived from the
:py:class:`PIL.ImageFile.ImageFile` base class. This class should provide an
``_open`` method, which reads the file header and sets at least the internal
``_size`` and ``_mode`` attributes so that :py:attr:`~PIL.Image.Image.mode` and
:py:attr:`~PIL.Image.Image.size` are populated. To be able to load the file,
the method must also create a list of ``tile`` descriptors, which contain a
decoder name, extents of the tile, and any decoder-specific data. The format
handler class must be explicitly registered, via a call to the
:py:mod:`~PIL.Image` module.

.. note:: For performance reasons, it is important that the
  ``_open`` method quickly rejects files that do not have the
  appropriate contents.

Example
-------

The following plugin supports a simple format, which has a 128-byte header
consisting of the words “SPAM” followed by the width, height, and pixel size in
bits. The header fields are separated by spaces. The image data follows
directly after the header, and can be either bi-level, grayscale, or 24-bit
true color.

**SpamImagePlugin.py**::

    from PIL import Image, ImageFile


    def _accept(prefix: bytes) -> bool:
        return prefix.startswith(b"SPAM")


    class SpamImageFile(ImageFile.ImageFile):

        format = "SPAM"
        format_description = "Spam raster image"

        def _open(self) -> None:

            header = self.fp.read(128).split()

            # size in pixels (width, height)
            self._size = int(header[1]), int(header[2])

            # mode setting
            bits = int(header[3])
            if bits == 1:
                self._mode = "1"
            elif bits == 8:
                self._mode = "L"
            elif bits == 24:
                self._mode = "RGB"
            else:
                msg = "unknown number of bits"
                raise SyntaxError(msg)

            # data descriptor
            self.tile = [ImageFile._Tile("raw", (0, 0) + self.size, 128, (self.mode, 0, 1))]


    Image.register_open(SpamImageFile.format, SpamImageFile, _accept)

    Image.register_extensions(
        SpamImageFile.format,
        [
            ".spam",
            ".spa",  # DOS version
        ],
    )


The format handler must always set the internal ``_size`` and ``_mode``
attributes so that :py:attr:`~PIL.Image.Image.size` and
:py:attr:`~PIL.Image.Image.mode` are populated. If these are not set, the file
cannot be opened. To simplify the plugin, the calling code considers exceptions
like :py:exc:`SyntaxError`, :py:exc:`KeyError`, :py:exc:`IndexError`,
:py:exc:`EOFError` and :py:exc:`struct.error` as a failure to identify the
file.

Note that the image plugin must be explicitly registered using
:py:func:`PIL.Image.register_open`. Although not required, it is also a good
idea to register any extensions used by this format.

Once the plugin has been imported, it can be used::

    from PIL import Image
    import SpamImagePlugin

    with Image.open("hopper.spam") as im:
        pass

The ``tile`` attribute
----------------------

To be able to read the file as well as just identifying it, the ``tile``
attribute must also be set. This attribute consists of a list of tile
descriptors, where each descriptor specifies how data should be loaded to a
given region in the image.

In most cases, only a single descriptor is used, covering the full image.
:py:class:`.PsdImagePlugin.PsdImageFile` uses multiple tiles to combine
channels within a single layer, given that the channels are stored separately,
one after the other.

The tile descriptor is a 4-tuple with the following contents::

    (decoder, region, offset, parameters)

The fields are used as follows:

**decoder**
    Specifies which decoder to use. The ``raw`` decoder used here supports
    uncompressed data, in a variety of pixel formats. For more information on
    this decoder, see the description below.

    A list of C decoders can be seen under codecs section of the function array
    in :file:`_imaging.c`. Python decoders are registered within the relevant
    plugins.

**region**
    A 4-tuple specifying where to store data in the image.

**offset**
    Byte offset from the beginning of the file to image data.

**parameters**
    Parameters to the decoder. The contents of this field depends on the
    decoder specified by the first field in the tile descriptor tuple. If the
    decoder doesn’t need any parameters, use :data:`None` for this field.

Note that the ``tile`` attribute contains a list of tile descriptors,
not just a single descriptor.

Decoders
========

The raw decoder
---------------

The ``raw`` decoder is used to read uncompressed data from an image file. It
can be used with most uncompressed file formats, such as PPM, BMP, uncompressed
TIFF, and many others. To use the raw decoder with the
:py:func:`PIL.Image.frombytes` function, use the following syntax::

    image = Image.frombytes(
        mode, size, data, "raw",
        raw_mode, stride, orientation
        )

When used in a tile descriptor, the parameter field should look like::

    (raw_mode, stride, orientation)

The fields are used as follows:

**raw_mode**
    The pixel layout used in the file, and is used to properly convert data to
    PIL’s internal layout. For a summary of the available formats, see the
    table below.

**stride**
    The distance in bytes between two consecutive lines in the image. If 0, the
    image is assumed to be packed (no padding between lines). If omitted, the
    stride defaults to 0.

**orientation**
    Whether the first line in the image is the top line on the screen (1), or
    the bottom line (-1). If omitted, the orientation defaults to 1.

The **raw mode** field is used to determine how the data should be unpacked to
match PIL’s internal pixel layout. PIL supports a large set of raw modes; for a
complete list, see the table in the :file:`Unpack.c` module. The following
table describes some commonly used **raw modes**:

+-----------+-------------------------------------------------------------------+
| mode      | description                                                       |
+===========+===================================================================+
| ``1``     | | 1-bit bilevel, stored with the leftmost pixel in the most       |
|           | | significant bit. 0 means black, 1 means white.                  |
+-----------+-------------------------------------------------------------------+
| ``1;I``   | | 1-bit inverted bilevel, stored with the leftmost pixel in the   |
|           | | most significant bit. 0 means white, 1 means black.             |
+-----------+-------------------------------------------------------------------+
| ``1;R``   | | 1-bit reversed bilevel, stored with the leftmost pixel in the   |
|           | | least significant bit. 0 means black, 1 means white.            |
+-----------+-------------------------------------------------------------------+
| ``L``     | 8-bit grayscale. 0 means black, 255 means white.                  |
+-----------+-------------------------------------------------------------------+
| ``L;I``   | 8-bit inverted grayscale. 0 means white, 255 means black.         |
+-----------+-------------------------------------------------------------------+
| ``P``     | 8-bit palette-mapped image.                                       |
+-----------+-------------------------------------------------------------------+
| ``RGB``   | 24-bit true colour, stored as (red, green, blue).                 |
+-----------+-------------------------------------------------------------------+
| ``BGR``   | 24-bit true colour, stored as (blue, green, red).                 |
+-----------+-------------------------------------------------------------------+
| ``RGBX``  | | 24-bit true colour, stored as (red, green, blue, pad). The pad  |
|           | | pixels may vary.                                                |
+-----------+-------------------------------------------------------------------+
| ``RGB;L`` | | 24-bit true colour, line interleaved (first all red pixels, then|
|           | | all green pixels, finally all blue pixels).                     |
+-----------+-------------------------------------------------------------------+

Note that for the most common cases, the raw mode is simply the same as the mode.

The Python Imaging Library supports many other decoders, including JPEG, PNG,
and PackBits. For details, see the :file:`decode.c` source file, and the
standard plugin implementations provided with the library.

Decoding floating point data
----------------------------

PIL provides some special mechanisms to allow you to load a wide variety of
formats into a mode ``F`` (floating point) image memory.

You can use the ``raw`` decoder to read images where data is packed in any
standard machine data type, using one of the following raw modes:

============ =======================================
mode         description
============ =======================================
``F``        32-bit native floating point.
``F;8``      8-bit unsigned integer.
``F;8S``     8-bit signed integer.
``F;16``     16-bit little endian unsigned integer.
``F;16S``    16-bit little endian signed integer.
``F;16B``    16-bit big endian unsigned integer.
``F;16BS``   16-bit big endian signed integer.
``F;16N``    16-bit native unsigned integer.
``F;16NS``   16-bit native signed integer.
``F;32``     32-bit little endian unsigned integer.
``F;32S``    32-bit little endian signed integer.
``F;32B``    32-bit big endian unsigned integer.
``F;32BS``   32-bit big endian signed integer.
``F;32N``    32-bit native unsigned integer.
``F;32NS``   32-bit native signed integer.
``F;32F``    32-bit little endian floating point.
``F;32BF``   32-bit big endian floating point.
``F;32NF``   32-bit native floating point.
``F;64F``    64-bit little endian floating point.
``F;64BF``   64-bit big endian floating point.
``F;64NF``   64-bit native floating point.
============ =======================================

The bit decoder
---------------

If the raw decoder cannot handle your format, PIL also provides a special “bit”
decoder that can be used to read various packed formats into a floating point
image memory.

To use the bit decoder with the :py:func:`PIL.Image.frombytes` function, use
the following syntax::

    image = Image.frombytes(
        mode, size, data, "bit",
        bits, pad, fill, sign, orientation
        )

When used in a tile descriptor, the parameter field should look like::

    (bits, pad, fill, sign, orientation)

The fields are used as follows:

**bits**
    Number of bits per pixel (2-32). No default.

**pad**
    Padding between lines, in bits. This is either 0 if there is no padding, or
    8 if lines are padded to full bytes. If omitted, the pad value defaults to
    8.

**fill**
    Controls how data are added to, and stored from, the decoder bit buffer.

**fill=0**
    Add bytes to the LSB end of the decoder buffer; store pixels from the MSB
    end.

**fill=1**
    Add bytes to the MSB end of the decoder buffer; store pixels from the MSB
    end.

**fill=2**
    Add bytes to the LSB end of the decoder buffer; store pixels from the LSB
    end.

**fill=3**
    Add bytes to the MSB end of the decoder buffer; store pixels from the LSB
    end.

    If omitted, the fill order defaults to 0.

**sign**
    If non-zero, bit fields are sign extended. If zero or omitted, bit fields
    are unsigned.

**orientation**
    Whether the first line in the image is the top line on the screen (1), or
    the bottom line (-1). If omitted, the orientation defaults to 1.

.. _file-codecs:

Writing your own file codec in C
================================

There are 3 stages in a file codec's lifetime:

1. Setup: Pillow looks for a function in the decoder or encoder registry,
   falling back to a function named ``[codecname]_decoder`` or
   ``[codecname]_encoder`` on the internal core image object. That function is
   called with the ``args`` tuple from the ``tile``.

2. Transforming: The codec's ``decode`` or ``encode`` function is repeatedly
   called with chunks of image data.

3. Cleanup: If the codec has registered a cleanup function, it will
   be called at the end of the transformation process, even if there was an
   exception raised.


Setup
-----

The current conventions are that the codec setup function is named
``PyImaging_[codecname]DecoderNew`` or ``PyImaging_[codecname]EncoderNew``
and defined in ``decode.c`` or ``encode.c``. The Python binding for it is
named ``[codecname]_decoder`` or ``[codecname]_encoder`` and is set up from
within the ``_imaging.c`` file in the codecs section of the function array.

The setup function needs to call ``PyImaging_DecoderNew`` or
``PyImaging_EncoderNew`` and at the very least, set the ``decode`` or
``encode`` function pointer. The fields of interest in this object are:

**decode**/**encode**
  Function pointer to the decode or encode function, which has access to
  ``im``, ``state``, and the buffer of data to be transformed.

**cleanup**
  Function pointer to the cleanup function, has access to ``state``.

**im**
  The target image, will be set by Pillow.

**state**
  An ImagingCodecStateInstance, will be set by Pillow. The ``context``
  member is an opaque struct that can be used by the codec to store
  any format specific state or options.

**pulls_fd**/**pushes_fd**
  If the decoder has ``pulls_fd`` or the encoder has ``pushes_fd`` set to 1,
  ``state->fd`` will be a pointer to the Python file-like object. The codec may
  use the functions in ``codec_fd.c`` to read or write directly with the file
  like object rather than have the data pushed through a buffer.

  .. versionadded:: 3.3.0


Transforming
------------

The decode or encode function is called with the target (core) image, the codec
state structure, and a buffer of data to be transformed.

It is the codec's responsibility to pull as much data as possible out of the
buffer and return the number of bytes consumed. The next call to the codec will
include the previous unconsumed tail. The codec function will be called
multiple times as the data is processed.

Alternatively, if ``pulls_fd`` or ``pushes_fd`` is set, then the decode or
encode function is called once, with an empty buffer. It is the codec's
responsibility to transform the entire tile in that one call.  Using this will
provide a codec with more freedom, but that freedom may mean increased memory
usage if the entire tile is held in memory at once by the codec.

If an error occurs, set ``state->errcode`` and return -1.

Return -1 on success, without setting the errcode.

Cleanup
-------

The cleanup function is called after the codec returns a negative
value, or if there is an error. This function should free any allocated
memory and release any resources from external libraries.

.. _file-codecs-py:

Writing your own file codec in Python
=====================================

Python file decoders and encoders should derive from
:py:class:`PIL.ImageFile.PyDecoder` and :py:class:`PIL.ImageFile.PyEncoder`
respectively, and should at least override the decode or encode method.
They should be registered using :py:meth:`PIL.Image.register_decoder` and
:py:meth:`PIL.Image.register_encoder`. As in the C implementation of
the file codecs, there are three stages in the lifetime of a
Python-based file codec:

1. Setup: Pillow looks for the codec in the decoder or encoder registry, then
   instantiates the class.

2. Transforming: The instance's ``decode`` method is repeatedly called with
   a buffer of data to be interpreted, or the ``encode`` method is repeatedly
   called with the size of data to be output.

   Alternatively, if the decoder's ``_pulls_fd`` property (or the encoder's
   ``_pushes_fd`` property) is set to ``True``, then ``decode`` and ``encode``
   will only be called once. In the decoder, ``self.fd`` can be used to access
   the file-like object. Using this will provide a codec with more freedom, but
   that freedom may mean increased memory usage if the entire file is held in
   memory at once by the codec.

   In ``decode``, once the data has been interpreted, ``set_as_raw`` can be
   used to populate the image.

3. Cleanup: The instance's ``cleanup`` method is called once the transformation
   is complete. This can be used to clean up any resources used by the codec.

   If you set ``_pulls_fd`` or ``_pushes_fd`` to ``True`` however, then you
   probably chose to perform any cleanup tasks at the end of ``decode`` or
   ``encode``.

For an example :py:class:`PIL.ImageFile.PyDecoder`, see `DdsImagePlugin
<https://github.com/python-pillow/Pillow/blob/main/docs/example/DdsImagePlugin.py>`_.
For a plugin that uses both :py:class:`PIL.ImageFile.PyDecoder` and
:py:class:`PIL.ImageFile.PyEncoder`, see `BlpImagePlugin
<https://github.com/python-pillow/Pillow/blob/main/src/PIL/BlpImagePlugin.py>`_

---

### Installation Basic Installation (`docs/installation/basic-installation.rst`)

.. raw:: html

    <script>
    document.addEventListener('DOMContentLoaded', function() {
      activateTab(getOS());
    });
    </script>

.. _basic-installation:

Basic installation
==================

.. note::

    The following instructions will install Pillow with support for
    most common image formats. See :ref:`external-libraries` for a
    full list of external libraries supported.

Install Pillow with :command:`pip`::

    python3 -m pip install --upgrade pip
    python3 -m pip install --upgrade Pillow

Optionally, install :pypi:`defusedxml` for Pillow to read XMP data,
and :pypi:`olefile` for Pillow to read FPX and MIC images::

    python3 -m pip install --upgrade defusedxml olefile


.. tab:: Linux

    We provide binaries for Linux for each of the supported Python
    versions in the manylinux wheel format. These include support for all
    optional libraries except libimagequant. Raqm support requires
    FriBiDi to be installed separately::

        python3 -m pip install --upgrade pip
        python3 -m pip install --upgrade Pillow

    Most major Linux distributions, including Fedora, Ubuntu and ArchLinux
    also include Pillow in packages that previously contained PIL e.g.
    ``python-imaging``. Debian splits it into two packages, ``python3-pil``
    and ``python3-pil.imagetk``.

.. tab:: macOS

    We provide binaries for macOS for each of the supported Python
    versions in the wheel format. These include support for all optional
    libraries except libimagequant. Raqm support requires
    FriBiDi to be installed separately::

        python3 -m pip install --upgrade pip
        python3 -m pip install --upgrade Pillow

    While we provide binaries for both x86-64 and arm64, we do not provide universal2
    binaries. However, it is simple to combine our current binaries to create one::

        python3 -m pip download --only-binary=:all: --platform macosx_10_10_x86_64 Pillow
        python3 -m pip download --only-binary=:all: --platform macosx_11_0_arm64 Pillow
        python3 -m pip install delocate

    Then, with the names of the downloaded wheels, use Python to combine them::

        from delocate.fuse import fuse_wheels
        fuse_wheels('Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl', 'Pillow-9.4.0-cp39-cp39-macosx_11_0_arm64.whl', 'Pillow-9.4.0-cp39-cp39-macosx_11_0_universal2.whl')

.. tab:: Windows

    We provide Pillow binaries for Windows compiled for the matrix of supported
    Pythons in the wheel format. These include x86, x86-64 and arm64 versions.
    These binaries include support
    for all optional libraries except libimagequant and libxcb. Raqm support
    requires FriBiDi to be installed separately::

        python3 -m pip install --upgrade pip
        python3 -m pip install --upgrade Pillow

    To install Pillow in MSYS2, see :ref:`building-from-source`.

.. tab:: FreeBSD

    Pillow can be installed on FreeBSD via the official Ports or Packages systems:

    **Ports**::

        cd /usr/ports/graphics/py-pillow && make install clean

    **Packages**::

        pkg install py312-pillow

    .. note::

        The `Pillow FreeBSD port
        <https://www.freshports.org/graphics/py-pillow/>`_ and packages
        are tested by the ports team with all supported FreeBSD versions.

---

### Installation Building From Source (`docs/installation/building-from-source.rst`)

.. raw:: html

    <script>
    document.addEventListener('DOMContentLoaded', function() {
      activateTab(getOS());
    });
    </script>

.. _building-from-source:

Building from source
====================

.. _external-libraries:

External libraries
------------------

.. note::

    You **do not need to install all supported external libraries** to
    use Pillow's basic features. **Zlib** and **libjpeg** are required
    by default.

.. note::

   There are Dockerfiles in our `Docker images repo
   <https://github.com/python-pillow/docker-images>`_ to install the
   dependencies for some operating systems.

Many of Pillow's features require external libraries:

* **libjpeg** provides JPEG functionality.

  * Pillow has been tested with libjpeg versions **6b**, **8**, **9-9d** and
    libjpeg-turbo version **8**.
  * Starting with Pillow 3.0.0, libjpeg is required by default. It can be
    disabled with the ``-C jpeg=disable`` flag.

* **zlib** provides access to compressed PNGs

  * Starting with Pillow 3.0.0, zlib is required by default. It can be
    disabled with the ``-C zlib=disable`` flag.

* **libtiff** provides compressed TIFF functionality

  * Pillow has been tested with libtiff versions **4.0-4.7.1**

* **libfreetype** provides type related services

* **littlecms** provides color management

  * Pillow version 2.2.1 and below uses liblcms1, Pillow 2.3.0 and
    above uses liblcms2. Tested with **1.19** and **2.7-2.19.1**.

* **libwebp** provides the WebP format.

* **openjpeg** provides JPEG 2000 functionality.

  * Pillow has been tested with openjpeg **2.0.0**, **2.1.0**, **2.3.1**,
    **2.4.0**, **2.5.0**, **2.5.2**, **2.5.3** and **2.5.4**.
  * Pillow does **not** support the earlier **1.5** series which ships
    with Debian Jessie.

* **libimagequant** provides improved color quantization

  * Pillow has been tested with libimagequant **2.6-4.4.1**
  * Libimagequant is licensed GPLv3, which is more restrictive than
    the Pillow license, therefore we will not be distributing binaries
    with libimagequant support enabled.

* **libraqm** provides complex text layout support.

  * libraqm provides bidirectional text support (using FriBiDi),
    shaping (using HarfBuzz), and proper script itemization. As a
    result, Raqm can support most writing systems covered by Unicode.
  * libraqm depends on the following libraries: FreeType, HarfBuzz,
    FriBiDi, make sure that you install them before installing libraqm
    if not available as package in your system.
  * Setting text direction or font features is not supported without libraqm.
  * Pillow wheels since version 8.2.0 include a modified version of libraqm that
    loads libfribidi at runtime if it is installed.
    On Windows this requires compiling FriBiDi and installing ``fribidi.dll``
    into a directory listed in the `Dynamic-link library search order (Microsoft Learn)
    <https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#search-order-for-unpackaged-apps>`_
    (``fribidi-0.dll`` or ``libfribidi-0.dll`` are also detected).
    See `Build Options`_ to see how to build this version.
  * Previous versions of Pillow (5.0.0 to 8.1.2) linked libraqm dynamically at runtime.

* **libxcb** provides X11 screengrab support.

* **libavif** provides support for the AVIF format.

  * Pillow requires libavif version **1.0.0** or greater.
  * libavif is merely an API that wraps AVIF codecs. If you are compiling
    libavif from source, you will also need to install both an AVIF encoder
    and decoder, such as rav1e and dav1d, or libaom, which both encodes and
    decodes AVIF images.

.. tab:: Linux

    If you didn't build Python from source, make sure you have Python's
    development libraries installed.

    In Debian or Ubuntu::

        sudo apt-get install python3-dev python3-setuptools

    In Fedora, the command is::

        sudo dnf install python3-devel redhat-rpm-config

    In Alpine, the command is::

        sudo apk add python3-dev py3-setuptools

    .. Note:: ``redhat-rpm-config`` is required on Fedora 23, but not earlier versions.

    Prerequisites for **Ubuntu 16.04 LTS - 26.04 LTS** are installed with::

        sudo apt-get install libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev \
            libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk \
            libharfbuzz-dev libfribidi-dev libxcb1-dev

    To install libraqm, ``sudo apt-get install meson`` and then see
    ``depends/install_raqm.sh``.

    Build prerequisites for libavif on Ubuntu are installed with::

        sudo apt-get install cmake ninja-build nasm

    Then see ``depends/install_libavif.sh`` to build and install libavif.

    Prerequisites are installed on recent **Red Hat**, **CentOS** or **Fedora** with::

        sudo dnf install libtiff-devel libjpeg-devel openjpeg2-devel zlib-devel \
            freetype-devel lcms2-devel libwebp-devel tcl-devel tk-devel \
            harfbuzz-devel fribidi-devel libraqm-devel libimagequant-devel libxcb-devel

    Note that the package manager may be yum or DNF, depending on the
    exact distribution.

    Prerequisites are installed for **Alpine** with::

        sudo apk add tiff-dev jpeg-dev openjpeg-dev zlib-dev freetype-dev lcms2-dev \
            libwebp-dev tcl-dev tk-dev harfbuzz-dev fribidi-dev libimagequant-dev \
            libxcb-dev libpng-dev

    See also the ``Dockerfile``\s in the Test Infrastructure repo
    (https://github.com/python-pillow/docker-images) for a known working
    install process for other tested distros.

.. tab:: macOS

    The Xcode command line tools are required to compile portions of
    Pillow. The tools are installed by running ``xcode-select --install``
    from the command line. The command line tools are required even if you
    have the full Xcode package installed.  It may be necessary to run
    ``sudo xcodebuild -license`` to accept the license prior to using the
    tools.

    The easiest way to install external libraries is via `Homebrew
    <https://brew.sh/>`_. After you install Homebrew, run::

        brew install libavif libjpeg libraqm libtiff little-cms2 openjpeg webp

    If you would like to use libavif with more codecs than just aom, then
    instead of installing libavif through Homebrew directly, you can use
    Homebrew to install libavif's build dependencies::

        brew install aom dav1d rav1e svt-av1

    Then see ``depends/install_libavif.sh`` to install libavif.

.. tab:: Windows

    We recommend you use prebuilt wheels from PyPI.
    If you wish to compile Pillow manually, you can use the build scripts
    in the ``winbuild`` directory used for CI testing and development.
    These scripts require Visual Studio 2017 or newer and NASM.

    The scripts also install Pillow from the local copy of the source code, so the
    `Installing`_ instructions will not be necessary afterwards.

.. tab:: Windows using MSYS2/MinGW

    To build Pillow using MSYS2, make sure you run the **MSYS2 MinGW 32-bit** or
    **MSYS2 MinGW 64-bit** console, *not* **MSYS2** directly.

    The following instructions target the 64-bit build, for 32-bit
    replace all occurrences of ``mingw-w64-x86_64-`` with ``mingw-w64-i686-``.

    Make sure you have Python and GCC installed::

        pacman -S \
            mingw-w64-x86_64-gcc \
            mingw-w64-x86_64-python \
            mingw-w64-x86_64-python-pip \
            mingw-w64-x86_64-python-setuptools

    Prerequisites are installed on **MSYS2 MinGW 64-bit** with::

        pacman -S \
            mingw-w64-x86_64-libjpeg-turbo \
            mingw-w64-x86_64-zlib \
            mingw-w64-x86_64-libtiff \
            mingw-w64-x86_64-freetype \
            mingw-w64-x86_64-lcms2 \
            mingw-w64-x86_64-libwebp \
            mingw-w64-x86_64-openjpeg2 \
            mingw-w64-x86_64-libimagequant \
            mingw-w64-x86_64-libraqm \
            mingw-w64-x86_64-libavif

.. tab:: FreeBSD

    .. Note:: Only FreeBSD 15.1 tested

    Make sure you have Python's development libraries installed::

        sudo pkg install python3

    Prerequisites are installed on **FreeBSD 15.1** with::

        sudo pkg install jpeg-turbo tiff webp lcms2 freetype2 openjpeg harfbuzz fribidi libxcb libavif libraqm libimagequant

.. tab:: Android

    Basic Android support has been added for compilation within the Termux
    environment. The dependencies can be installed by::

        pkg install -y python ndk-sysroot clang make \
            libjpeg-turbo

    This has been tested within the Termux app on ChromeOS, on x86.

Installing
----------

Once you have installed the prerequisites, to install Pillow from the source
code on PyPI, run::

    python3 -m pip install --upgrade pip
    python3 -m pip install --upgrade Pillow --no-binary :all:

If the prerequisites are installed in the standard library locations
for your machine (e.g. :file:`/usr` or :file:`/usr/local`), no
additional configuration should be required. If they are installed in
a non-standard location, you may need to configure setuptools to use
those locations by editing :file:`setup.py` or
:file:`pyproject.toml`, or by adding environment variables on the command
line::

    CFLAGS="-I/usr/pkg/include" python3 -m pip install --upgrade Pillow --no-binary :all:

If Pillow has been previously built without the required
prerequisites, it may be necessary to manually clear the pip cache or
build without cache using the ``--no-cache-dir`` option to force a
build with newly installed external libraries.

If you would like to install from a local copy of the source code instead, you
can clone from GitHub with ``git clone https://github.com/python-pillow/Pillow``
or download and extract the `compressed archive from PyPI`_.

After navigating to the Pillow directory, run::

    python3 -m pip install --upgrade pip
    python3 -m pip install .

.. _compressed archive from PyPI: https://pypi.org/project/pillow/#files

Build options
^^^^^^^^^^^^^

* Config setting: ``-C parallel=n``. Can also be given
  with environment variable: ``MAX_CONCURRENCY=n``. Pillow can use
  multiprocessing to build the extensions. Setting ``-C parallel=n``
  sets the number of CPUs to use to ``n``, or can disable parallel building by
  using a setting of 1. By default, it uses as many CPUs as are present.

* Config settings: ``-C zlib=disable``, ``-C jpeg=disable``,
  ``-C tiff=disable``, ``-C freetype=disable``, ``-C raqm=disable``,
  ``-C lcms=disable``, ``-C webp=disable``,
  ``-C jpeg2000=disable``, ``-C imagequant=disable``, ``-C xcb=disable``,
  ``-C avif=disable``.
  Disable building the corresponding feature even if the development
  libraries are present on the building machine.

* Config settings: ``-C zlib=enable``, ``-C jpeg=enable``,
  ``-C tiff=enable``, ``-C freetype=enable``, ``-C raqm=enable``,
  ``-C lcms=enable``, ``-C webp=enable``,
  ``-C jpeg2000=enable``, ``-C imagequant=enable``, ``-C xcb=enable``,
  ``-C avif=enable``.
  Require that the corresponding feature is built. The build will raise
  an exception if the libraries are not found. Tcl and Tk must be used
  together.

* Config settings: ``-C raqm=vendor``, ``-C fribidi=vendor``.
  These flags are used to compile a modified version of libraqm and
  a shim that dynamically loads libfribidi at runtime. These are
  used to compile the standard Pillow wheels. Compiling libraqm requires
  a C99-compliant compiler.

* Config setting: ``-C platform-guessing=disable``. Skips all of the
  platform dependent guessing of include and library directories for
  automated build systems that configure the proper paths in the
  environment variables (e.g. Buildroot).

* Config setting: ``-C debug=true``. Adds a debugging flag to the include and
  library search process to dump all paths searched for and found to stdout.


Sample usage::

    python3 -m pip install --upgrade Pillow -C [feature]=enable

.. _old-versions:

Old versions
============

You can download old distributions from the `release history at PyPI
<https://pypi.org/project/pillow/#history>`_ and by direct URL access
eg. https://pypi.org/project/pillow/1.0/.

---

### Installation Index (`docs/installation/index.rst`)

Installation
============

.. toctree::
  :maxdepth: 2

  basic-installation
  python-support
  platform-support
  building-from-source

---

### Installation Platform Support (`docs/installation/platform-support.rst`)

.. _platform-support:

Platform support
================

Current platform support for Pillow. Binary distributions are
contributed for each release on a volunteer basis, but the source
should compile and run everywhere platform support is listed. In
general, we aim to support all current versions of Linux, macOS, and
Windows.

Continuous integration targets
------------------------------

These platforms are built and tested for every change.

+----------------------------------+----------------------------+---------------------+
| Operating system                 | Tested Python versions     | Tested architecture |
+==================================+============================+=====================+
| Alpine                           | 3.14                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| Amazon Linux 2023                | 3.11                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| Arch                             | 3.14                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| CentOS Stream 9                  | 3.11                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| CentOS Stream 10                 | 3.12                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| Debian 13 Trixie                 | 3.13                       | x86, x86-64         |
+----------------------------------+----------------------------+---------------------+
| Fedora 44                        | 3.14                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| Gentoo                           | 3.14                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| macOS 26 Tahoe                   | 3.12, 3.13, 3.14, 3.15,    | arm64               |
|                                  | PyPy3                      |                     |
|                                  +----------------------------+---------------------+
|                                  | 3.11                       | x86-64              |
+----------------------------------+----------------------------+---------------------+
| Ubuntu Linux 24.04 LTS (Noble)   | 3.11, 3.12, 3.13, 3.14,    | x86-64              |
|                                  | 3.15, PyPy3                |                     |
+----------------------------------+----------------------------+---------------------+
| Ubuntu Linux 26.04 LTS (Resolute)| 3.14                       | x86-64, arm64v8,    |
|                                  |                            | ppc64le, s390x      |
+----------------------------------+----------------------------+---------------------+
| Windows Server 2022              | 3.11                       | x86                 |
+----------------------------------+----------------------------+---------------------+
| Windows Server 2025              | 3.12, 3.13, 3.14, 3.15,    | x86-64              |
|                                  | PyPy3                      |                     |
|                                  +----------------------------+---------------------+
|                                  | 3.14 (MinGW)               | x86-64              |
+----------------------------------+----------------------------+---------------------+


Other platforms
---------------

These platforms have been reported to work at the versions mentioned.

.. note::

    Contributors please test Pillow on your platform then update this
    document and send a pull request.

+----------------------------------+-----------------------------+------------------+--------------+
| Operating system                 | | Tested Python             | | Latest tested  | | Tested     |
|                                  | | versions                  | | Pillow version | | processors |
+==================================+=============================+==================+==============+
| macOS 27 Golden Gate             | 3.11, 3.12, 3.13, 3.14, 3.15| 13.0.0           |arm           |
|                                  +-----------------------------+------------------+              |
|                                  | 3.10                        | 12.3.0           |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 26 Tahoe                   | 3.10, 3.11, 3.12, 3.13, 3.14| 12.3.0           |arm           |
|                                  +-----------------------------+------------------+              |
|                                  | 3.9                         | 11.3.0           |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 15 Sequoia                 | 3.11, 3.12, 3.13, 3.14, 3.15| 13.0.0           |arm           |
|                                  +-----------------------------+------------------+              |
|                                  | 3.10                        | 12.3.0           |              |
|                                  +-----------------------------+------------------+              |
|                                  | 3.9                         | 11.3.0           |              |
|                                  +-----------------------------+------------------+              |
|                                  | 3.8                         | 10.4.0           |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 14 Sonoma                  | 3.8, 3.9, 3.10, 3.11, 3.12  | 10.4.0           |arm           |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 13 Ventura                 | 3.8, 3.9, 3.10, 3.11        | 10.0.1           |arm           |
|                                  +-----------------------------+------------------+              |
|                                  | 3.7                         | 9.5.0            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 12 Monterey                | 3.7, 3.8, 3.9, 3.10, 3.11   | 9.3.0            |arm           |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 11 Big Sur                 | 3.7, 3.8, 3.9, 3.10         | 8.4.0            |arm           |
|                                  +-----------------------------+------------------+--------------+
|                                  | 3.7, 3.8, 3.9, 3.10, 3.11   | 9.4.0            |x86-64        |
|                                  +-----------------------------+------------------+              |
|                                  | 3.6                         | 8.4.0            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 10.15 Catalina             | 3.6, 3.7, 3.8, 3.9          | 8.3.2            |x86-64        |
|                                  +-----------------------------+------------------+              |
|                                  | 3.5                         | 7.2.0            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 10.14 Mojave               | 3.5, 3.6, 3.7, 3.8          | 7.2.0            |x86-64        |
|                                  +-----------------------------+------------------+              |
|                                  | 2.7                         | 6.0.0            |              |
|                                  +-----------------------------+------------------+              |
|                                  | 3.4                         | 5.4.1            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 10.13 High Sierra          | 2.7, 3.4, 3.5, 3.6          | 4.2.1            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| macOS 10.12 Sierra               | 2.7, 3.4, 3.5, 3.6          | 4.1.1            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Mac OS X 10.11 El Capitan        | 2.7, 3.4, 3.5, 3.6, 3.7     | 5.4.1            |x86-64        |
|                                  +-----------------------------+------------------+              |
|                                  | 3.3                         | 4.1.0            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| Mac OS X 10.9 Mavericks          | 2.7, 3.2, 3.3, 3.4          | 3.0.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Mac OS X 10.8 Mountain Lion      | 2.6, 2.7, 3.2, 3.3          |                  |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Redhat Linux 6                   | 2.6                         |                  |x86           |
+----------------------------------+-----------------------------+------------------+--------------+
| CentOS 6.3                       | 2.7, 3.3                    |                  |x86           |
+----------------------------------+-----------------------------+------------------+--------------+
| CentOS 8                         | 3.9                         | 9.0.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Fedora 23                        | 2.7, 3.4                    | 3.1.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Ubuntu Linux 12.04 LTS (Precise) | | 2.6, 3.2, 3.3, 3.4, 3.5   | 3.4.1            |x86,x86-64    |
|                                  | | PyPy5.3.1, PyPy3 v2.4.0   |                  |              |
|                                  +-----------------------------+------------------+--------------+
|                                  | 2.7                         | 4.3.0            |x86-64        |
|                                  +-----------------------------+------------------+--------------+
|                                  | 2.7, 3.2                    | 3.4.1            |ppc           |
+----------------------------------+-----------------------------+------------------+--------------+
| Ubuntu Linux 10.04 LTS (Lucid)   | 2.6                         | 2.3.0            |x86,x86-64    |
+----------------------------------+-----------------------------+------------------+--------------+
| Debian 8.2 Jessie                | 2.7, 3.4                    | 3.1.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Raspbian Jessie                  | 2.7, 3.4                    | 3.1.0            |arm           |
+----------------------------------+-----------------------------+------------------+--------------+
| Raspbian Stretch                 | 2.7, 3.5                    | 4.0.0            |arm           |
+----------------------------------+-----------------------------+------------------+--------------+
| Raspberry Pi OS                  | 3.6, 3.7, 3.8, 3.9          | 8.2.0            |arm           |
|                                  +-----------------------------+------------------+              |
|                                  | 2.7                         | 6.2.2            |              |
+----------------------------------+-----------------------------+------------------+--------------+
| Gentoo Linux                     | 2.7, 3.2                    | 2.1.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| FreeBSD 15.1                     | 3.12                        | 12.3.0           |arm64         |
+----------------------------------+-----------------------------+------------------+--------------+
| FreeBSD 11.1                     | 2.7, 3.4, 3.5, 3.6          | 4.3.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| FreeBSD 10.3                     | 2.7, 3.4, 3.5               | 4.2.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| FreeBSD 10.2                     | 2.7, 3.4                    | 3.1.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 11 23H2                  | 3.9, 3.10, 3.11, 3.12, 3.13 | 11.0.0           |arm64         |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 11 Pro                   | 3.11, 3.12                  | 10.2.0           |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 10                       | 3.7                         | 7.1.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 10/Cygwin 3.3            | 3.6, 3.7, 3.8, 3.9          | 8.4.0            |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 8.1 Pro                  | 2.6, 2.7, 3.2, 3.3, 3.4     | 2.4.0            |x86,x86-64    |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 8 Pro                    | 2.6, 2.7, 3.2, 3.3, 3.4a3   | 2.2.0            |x86,x86-64    |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows 7 Professional           | 3.7                         | 7.0.0            |x86,x86-64    |
+----------------------------------+-----------------------------+------------------+--------------+
| Windows Server 2008 R2 Enterprise| 3.3                         |                  |x86-64        |
+----------------------------------+-----------------------------+------------------+--------------+

---

### Installation Python Support (`docs/installation/python-support.rst`)

.. _python-support:

Python support
==============

Pillow supports these Python versions.

.. csv-table:: Newer versions
   :file: newer-versions.csv
   :header-rows: 1

.. csv-table:: Older versions
   :file: older-versions.csv
   :header-rows: 1

---

### Reference ExifTags (`docs/reference/ExifTags.rst`)

.. py:module:: PIL.ExifTags
.. py:currentmodule:: PIL.ExifTags

:py:mod:`~PIL.ExifTags` module
==============================

The :py:mod:`~PIL.ExifTags` module exposes several :py:class:`enum.IntEnum`
classes which provide constants and clear-text names for various well-known
EXIF tags.

.. py:data:: Base

    >>> from PIL.ExifTags import Base
    >>> Base.ImageDescription.value
    270
    >>> Base(270).name
    'ImageDescription'

.. py:data:: GPS

    >>> from PIL.ExifTags import GPS
    >>> GPS.GPSDestLatitude.value
    20
    >>> GPS(20).name
    'GPSDestLatitude'

.. py:data:: Interop

    >>> from PIL.ExifTags import Interop
    >>> Interop.RelatedImageFileFormat.value
    4096
    >>> Interop(4096).name
    'RelatedImageFileFormat'

.. py:data:: IFD

    >>> from PIL.ExifTags import IFD
    >>> IFD.Exif.value
    34665
    >>> IFD(34665).name
    'Exif'

.. py:data:: LightSource

    >>> from PIL.ExifTags import LightSource
    >>> LightSource.Unknown.value
    0
    >>> LightSource(0).name
    'Unknown'

Two of these values are also exposed as dictionaries.

.. py:data:: TAGS
    :type: dict

    The TAGS dictionary maps 16-bit integer EXIF tag enumerations to
    descriptive string names. For instance:

        >>> from PIL.ExifTags import TAGS
        >>> TAGS[0x010e]
        'ImageDescription'

.. py:data:: GPSTAGS
    :type: dict

    The GPSTAGS dictionary maps 8-bit integer EXIF GPS enumerations to
    descriptive string names. For instance:

        >>> from PIL.ExifTags import GPSTAGS
        >>> GPSTAGS[20]
        'GPSDestLatitude'

---

### Reference Image (`docs/reference/Image.rst`)

.. py:module:: PIL.Image
.. py:currentmodule:: PIL.Image

:py:mod:`~PIL.Image` module
===========================

The :py:mod:`~PIL.Image` module provides a class with the same name which is
used to represent a PIL image. The module also provides a number of factory
functions, including functions to load images from files, and to create new
images.

Examples
--------

Open, rotate, and display an image (using the default viewer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following script loads an image, rotates it 45 degrees, and displays it
using an external viewer (usually xv on Unix, and the Paint program on
Windows). ::

    from PIL import Image
    with Image.open("hopper.jpg") as im:
        im.rotate(45).show()

Create thumbnails
^^^^^^^^^^^^^^^^^

The following script creates nice thumbnails of all JPEG images in the
current directory preserving aspect ratios with 128x128 max resolution. ::

    from PIL import Image
    import glob, os

    size = 128, 128

    for infile in glob.glob("*.jpg"):
        file, ext = os.path.splitext(infile)
        with Image.open(infile) as im:
            im.thumbnail(size)
            im.save(file + ".thumbnail", "JPEG")

Functions
---------

.. autofunction:: open

    .. warning::
        To protect against potential DOS attacks caused by "`decompression bombs`_" (i.e. malicious files
        which decompress into a huge amount of data and are designed to crash or cause disruption by using up
        a lot of memory), Pillow will issue a ``DecompressionBombWarning`` if the number of pixels in an
        image is over a certain limit, :py:data:`MAX_IMAGE_PIXELS`.

        This threshold can be changed by setting :py:data:`MAX_IMAGE_PIXELS`. It can be disabled
        by setting ``Image.MAX_IMAGE_PIXELS = None``.

        If desired, the warning can be turned into an error with
        ``warnings.simplefilter('error', Image.DecompressionBombWarning)`` or suppressed entirely with
        ``warnings.simplefilter('ignore', Image.DecompressionBombWarning)``. See also
        `the logging documentation`_ to have warnings output to the logging facility instead of stderr.

        If the number of pixels is greater than twice :py:data:`MAX_IMAGE_PIXELS`, then a
        ``DecompressionBombError`` will be raised instead.

    .. _decompression bombs: https://en.wikipedia.org/wiki/Zip_bomb
    .. _the logging documentation: https://docs.python.org/3/library/logging.html#integration-with-the-warnings-module

Image processing
^^^^^^^^^^^^^^^^

.. autofunction:: alpha_composite
.. autofunction:: blend
.. autofunction:: composite
.. autofunction:: eval
.. autofunction:: merge

Constructing images
^^^^^^^^^^^^^^^^^^^

.. autofunction:: new
.. autofunction:: fromarray
.. autofunction:: fromarrow
.. autofunction:: frombytes
.. autofunction:: frombuffer

Generating images
^^^^^^^^^^^^^^^^^

.. autofunction:: effect_mandelbrot
.. autofunction:: effect_noise
.. autofunction:: linear_gradient
.. autofunction:: radial_gradient

Registering plugins
^^^^^^^^^^^^^^^^^^^

.. autofunction:: preinit
.. autofunction:: init

.. note::

    These functions are for use by plugin authors. They are called when a
    plugin is loaded as part of :py:meth:`~preinit()` or :py:meth:`~init()`.
    Application authors can ignore them.

.. autofunction:: register_open
.. autofunction:: register_mime
.. autofunction:: register_save
.. autofunction:: register_save_all
.. autofunction:: register_extension
.. autofunction:: register_extensions
.. autofunction:: registered_extensions
.. autofunction:: register_decoder
.. autofunction:: register_encoder

The Image class
---------------

.. autoclass:: PIL.Image.Image

An instance of the :py:class:`~PIL.Image.Image` class has the following
methods. Unless otherwise stated, all methods return a new instance of the
:py:class:`~PIL.Image.Image` class, holding the resulting image.


.. automethod:: PIL.Image.Image.alpha_composite
.. automethod:: PIL.Image.Image.apply_transparency
.. automethod:: PIL.Image.Image.convert

The following example converts an RGB image (linearly calibrated according to
ITU-R 709, using the D65 luminant) to the CIE XYZ color space::

    rgb2xyz = (
        0.412453, 0.357580, 0.180423, 0,
        0.212671, 0.715160, 0.072169, 0,
        0.019334, 0.119193, 0.950227, 0)
    out = im.convert("RGB", rgb2xyz)

.. automethod:: PIL.Image.Image.copy
.. automethod:: PIL.Image.Image.crop

This crops the input image with the provided coordinates::

    from PIL import Image

    with Image.open("hopper.jpg") as im:

        # The crop method from the Image module takes four coordinates as input.
        # The right can also be represented as (left+width)
        # and lower can be represented as (upper+height).
        (left, upper, right, lower) = (20, 20, 100, 100)

        # Here the image "im" is cropped and assigned to new variable im_crop
        im_crop = im.crop((left, upper, right, lower))


.. automethod:: PIL.Image.Image.draft
.. automethod:: PIL.Image.Image.effect_spread
.. automethod:: PIL.Image.Image.entropy
.. automethod:: PIL.Image.Image.filter

This blurs the input image using a filter from the ``ImageFilter`` module::

    from PIL import Image, ImageFilter

    with Image.open("hopper.jpg") as im:

        # Blur the input image using the filter ImageFilter.BLUR
        im_blurred = im.filter(filter=ImageFilter.BLUR)

.. automethod:: PIL.Image.Image.frombytes
.. automethod:: PIL.Image.Image.getbands

This helps to get the bands of the input image::

    from PIL import Image

    with Image.open("hopper.jpg") as im:
        print(im.getbands())  # Returns ('R', 'G', 'B')

.. automethod:: PIL.Image.Image.getbbox

This helps to get the bounding box coordinates of the input image::

    from PIL import Image

    with Image.open("hopper.jpg") as im:
        print(im.getbbox())
        # Returns four coordinates in the format (left, upper, right, lower)

.. automethod:: PIL.Image.Image.getchannel
.. automethod:: PIL.Image.Image.getcolors
.. automethod:: PIL.Image.Image.getdata
.. automethod:: PIL.Image.Image.get_flattened_data
.. automethod:: PIL.Image.Image.getexif
.. automethod:: PIL.Image.Image.getextrema
.. automethod:: PIL.Image.Image.getpalette
.. automethod:: PIL.Image.Image.getpixel
.. automethod:: PIL.Image.Image.getprojection
.. automethod:: PIL.Image.Image.getxmp
.. automethod:: PIL.Image.Image.histogram
.. automethod:: PIL.Image.Image.paste
.. automethod:: PIL.Image.Image.point
.. automethod:: PIL.Image.Image.putalpha
.. automethod:: PIL.Image.Image.putdata
.. automethod:: PIL.Image.Image.putpalette
.. automethod:: PIL.Image.Image.putpixel
.. automethod:: PIL.Image.Image.quantize
.. automethod:: PIL.Image.Image.reduce
.. automethod:: PIL.Image.Image.remap_palette
.. automethod:: PIL.Image.Image.resize

This resizes the given image from ``(width, height)`` to ``(width/2, height/2)``::

    from PIL import Image

    with Image.open("hopper.jpg") as im:

        # Provide the target width and height of the image
        (width, height) = (im.width // 2, im.height // 2)
        im_resized = im.resize((width, height))

.. automethod:: PIL.Image.Image.rotate

This rotates the input image by ``theta`` degrees counterclockwise::

    from PIL import Image

    with Image.open("hopper.jpg") as im:

        # Rotate the image by 60 degrees counterclockwise
        theta = 60
        # Angle is in degrees counterclockwise
        im_rotated = im.rotate(angle=theta)

.. automethod:: PIL.Image.Image.save
.. automethod:: PIL.Image.Image.seek
.. automethod:: PIL.Image.Image.show
.. automethod:: PIL.Image.Image.split
.. automethod:: PIL.Image.Image.tell
.. automethod:: PIL.Image.Image.thumbnail
.. automethod:: PIL.Image.Image.tobitmap
.. automethod:: PIL.Image.Image.tobytes
.. automethod:: PIL.Image.Image.transform
.. automethod:: PIL.Image.Image.transpose

This flips the input image by using the :data:`Transpose.FLIP_LEFT_RIGHT`
method. ::

    from PIL import Image

    with Image.open("hopper.jpg") as im:

        # Flip the image from left to right
        im_flipped = im.transpose(method=Image.Transpose.FLIP_LEFT_RIGHT)
        # To flip the image from top to bottom,
        # use the method "Image.Transpose.FLIP_TOP_BOTTOM"


.. automethod:: PIL.Image.Image.verify

.. automethod:: PIL.Image.Image.load
.. automethod:: PIL.Image.Image.close

Image attributes
----------------

Instances of the :py:class:`Image` class have the following attributes:

.. py:attribute:: Image.filename
    :type: str

    The filename or path of the source file. Only images created with the
    factory function ``open`` have a filename attribute. If the input is a
    file-like object, the filename attribute is set to an empty string.

.. py:attribute:: Image.format
    :type: Optional[str]

    The file format of the source file. For images created by the library
    itself (via a factory function, or by running a method on an existing
    image), this attribute is set to :data:`None`.

.. py:attribute:: Image.mode
    :type: str

    Image mode. This is a string specifying the pixel format used by the image.
    Typical values are “1”, “L”, “RGB”, or “CMYK.” See
    :ref:`concept-modes` for a full list.

.. py:attribute:: Image.size
    :type: tuple[int]

    Image size, in pixels. The size is given as a 2-tuple (width, height).

.. py:attribute:: Image.width
    :type: int

    Image width, in pixels.

.. py:attribute:: Image.height
    :type: int

    Image height, in pixels.

.. py:attribute:: Image.palette
    :type: Optional[PIL.ImagePalette.ImagePalette]

    Colour palette table, if any. If mode is "P" or "PA", this should be an
    instance of the :py:class:`~PIL.ImagePalette.ImagePalette` class.
    Otherwise, it should be set to :data:`None`.

.. py:attribute:: Image.info
    :type: dict

    A dictionary holding data associated with the image. This dictionary is
    used by file handlers to pass on various non-image information read from
    the file. See documentation for the various file handlers for details.

    Most methods ignore the dictionary when returning new images; since the
    keys are not standardized, it’s not possible for a method to know if the
    operation affects the dictionary. If you need the information later on,
    keep a reference to the info dictionary returned from the open method.

    Unless noted elsewhere, this dictionary does not affect saving files.

.. py:attribute:: Image.is_animated
    :type: bool

    ``True`` if this image has more than one frame, or ``False`` otherwise.

    This attribute is only defined by image plugins that support animated images.
    Plugins may leave this attribute undefined if they don't support loading
    animated images, even if the given format supports animated images.

    Given that this attribute is not present for all images, use
    ``getattr(image, "is_animated", False)`` to check if Pillow is aware of multiple
    frames in an image regardless of its format.

    .. seealso:: :attr:`~Image.n_frames`, :func:`~Image.seek` and :func:`~Image.tell`

.. py:attribute:: Image.n_frames
    :type: int

    The number of frames in this image.

    This attribute is only defined by image plugins that support animated images.
    Plugins may leave this attribute undefined if they don't support loading
    animated images, even if the given format supports animated images.

    Given that this attribute is not present for all images, use
    ``getattr(image, "n_frames", 1)`` to check the number of frames that Pillow is
    aware of in an image regardless of its format.

    .. seealso:: :attr:`~Image.is_animated`, :func:`~Image.seek` and :func:`~Image.tell`

.. autoattribute:: PIL.Image.Image.has_transparency_data

Classes
-------

.. autoclass:: PIL.Image.Exif
    :members:
    :undoc-members:
    :show-inheritance:
.. autoclass:: PIL.Image.ImagePointHandler
.. autoclass:: PIL.Image.ImagePointTransform
.. autoclass:: PIL.Image.ImageTransformHandler

Protocols
---------

.. autoclass:: SupportsArrayInterface
    :show-inheritance:
.. autoclass:: SupportsArrowArrayInterface
    :show-inheritance:
.. autoclass:: SupportsGetData
    :show-inheritance:
.. autoclass:: DecoderInput
    :show-inheritance:

Constants
---------

.. data:: NONE
.. data:: MAX_IMAGE_PIXELS

    Set to 89,478,485, approximately 0.25GB for a 24-bit (3 bpp) image.
    See :py:meth:`~PIL.Image.open` for more information about how this is used.

.. data:: WARN_POSSIBLE_FORMATS

    Set to false. If true, when an image cannot be identified, warnings will be raised
    from formats that attempted to read the data.

Transpose methods
^^^^^^^^^^^^^^^^^

Used to specify the :meth:`Image.transpose` method to use.

.. autoclass:: Transpose
    :members:
    :undoc-members:

Transform methods
^^^^^^^^^^^^^^^^^

Used to specify the :meth:`Image.transform` method to use.

.. py:class:: Transform

    .. py:attribute:: AFFINE

        Affine transform

    .. py:attribute:: EXTENT

        Cut out a rectangular subregion

    .. py:attribute:: PERSPECTIVE

        Perspective transform

    .. py:attribute:: QUAD

        Map a quadrilateral to a rectangle

    .. py:attribute:: MESH

        Map a number of source quadrilaterals in one operation

Resampling filters
^^^^^^^^^^^^^^^^^^

See :ref:`concept-filters` for details.

.. autoclass:: Resampling
    :members:
    :undoc-members:

Dither modes
^^^^^^^^^^^^

Used to specify the dithering method to use for the
:meth:`~Image.convert` and :meth:`~Image.quantize` methods.

.. py:class:: Dither

    .. py:attribute:: NONE

      No dither

    .. py:attribute:: ORDERED

      Not implemented

    .. py:attribute:: RASTERIZE

      Not implemented

    .. py:attribute:: FLOYDSTEINBERG

      Floyd-Steinberg dither

Palettes
^^^^^^^^

Used to specify the palette to use for the :meth:`~Image.convert` method.

.. autoclass:: Palette
    :members:
    :undoc-members:

Quantization methods
^^^^^^^^^^^^^^^^^^^^

Used to specify the quantization method to use for the :meth:`~Image.quantize` method.

.. py:class:: Quantize

    .. py:attribute:: MEDIANCUT

      Median cut. Default method, except for RGBA images. This method does not support
      RGBA images.

    .. py:attribute:: MAXCOVERAGE

      Maximum coverage. This method does not support RGBA images.

    .. py:attribute:: FASTOCTREE

      Fast octree. Default method for RGBA images.

    .. py:attribute:: LIBIMAGEQUANT

      libimagequant

      Check support using :py:func:`PIL.features.check_feature` with
      ``feature="libimagequant"``.

---

### Reference ImageChops (`docs/reference/ImageChops.rst`)

.. py:module:: PIL.ImageChops
.. py:currentmodule:: PIL.ImageChops

:py:mod:`~PIL.ImageChops` ("channel operations") module
=======================================================

The :py:mod:`~PIL.ImageChops` module contains a number of arithmetical image
operations, called channel operations (“chops”). These can be used for various
purposes, including special effects, image compositions, algorithmic painting,
and more.

For more pre-made operations, see :py:mod:`~PIL.ImageOps`.

At this time, most channel operations are only implemented for 8-bit images
(e.g. “L” and “RGB”).

Functions
---------

Most channel operations take one or two image arguments and return a new
image. Unless otherwise noted, the result of a channel operation is always
clipped to the range 0 to MAX (which is 255 for all modes supported by the
operations in this module).

.. autofunction:: PIL.ImageChops.add
.. autofunction:: PIL.ImageChops.add_modulo
.. autofunction:: PIL.ImageChops.blend
.. autofunction:: PIL.ImageChops.composite
.. autofunction:: PIL.ImageChops.constant
.. autofunction:: PIL.ImageChops.darker
.. autofunction:: PIL.ImageChops.difference
.. autofunction:: PIL.ImageChops.duplicate
.. autofunction:: PIL.ImageChops.invert
.. autofunction:: PIL.ImageChops.lighter
.. autofunction:: PIL.ImageChops.logical_and
.. autofunction:: PIL.ImageChops.logical_or
.. autofunction:: PIL.ImageChops.logical_xor
.. autofunction:: PIL.ImageChops.multiply
.. autofunction:: PIL.ImageChops.soft_light
.. autofunction:: PIL.ImageChops.hard_light
.. autofunction:: PIL.ImageChops.overlay
.. autofunction:: PIL.ImageChops.offset
.. autofunction:: PIL.ImageChops.screen
.. autofunction:: PIL.ImageChops.subtract
.. autofunction:: PIL.ImageChops.subtract_modulo

---

### Reference ImageCms (`docs/reference/ImageCms.rst`)

.. py:module:: PIL.ImageCms
.. py:currentmodule:: PIL.ImageCms

:py:mod:`~PIL.ImageCms` module
==============================

The :py:mod:`~PIL.ImageCms` module provides color profile management
support using the LittleCMS2 color management engine, based on Kevin
Cazabon's PyCMS library.

.. autoclass:: ImageCmsProfile
    :members:
    :special-members: __init__
.. autoclass:: ImageCmsTransform
    :members:
    :undoc-members:
    :show-inheritance:
.. autoexception:: PyCMSError

Constants
---------

.. autoclass:: Intent
    :members:
    :member-order: bysource
    :undoc-members:
    :show-inheritance:
.. autoclass:: Direction
    :members:
    :member-order: bysource
    :undoc-members:
    :show-inheritance:
.. autoclass:: Flags
    :members:
    :member-order: bysource
    :undoc-members:
    :show-inheritance:

Functions
---------

.. autofunction:: applyTransform
.. autofunction:: buildProofTransform
.. autofunction:: buildProofTransformFromOpenProfiles
.. autofunction:: buildTransform
.. autofunction:: buildTransformFromOpenProfiles
.. autofunction:: createProfile
.. autofunction:: getDefaultIntent
.. autofunction:: getOpenProfile
.. autofunction:: getProfileCopyright
.. autofunction:: getProfileDescription
.. autofunction:: getProfileInfo
.. autofunction:: getProfileManufacturer
.. autofunction:: getProfileModel
.. autofunction:: getProfileName
.. autofunction:: get_display_profile
.. autofunction:: isIntentSupported
.. autofunction:: profileToProfile

CmsProfile
----------

The ICC color profiles are wrapped in an instance of the class
:py:class:`~core.CmsProfile`.  The specification ICC.1:2010 contains more
information about the meaning of the values in ICC profiles.

For convenience, all XYZ-values are also given as xyY-values (so they
can be easily displayed in a chromaticity diagram, for example).

.. py:currentmodule:: PIL.ImageCms.core
.. py:class:: CmsProfile
    :canonical: PIL._imagingcms.CmsProfile

    .. py:attribute:: creation_date
        :type: datetime.datetime | None

        Date and time this profile was first created (see 7.2.1 of ICC.1:2010).

    .. py:attribute:: version
        :type: float

        The version number of the ICC standard that this profile follows
        (e.g. ``2.0``).

    .. py:attribute:: icc_version
        :type: int

        Same as ``version``, but in encoded format (see 7.2.4 of ICC.1:2010).

    .. py:attribute:: device_class
        :type: str

        4-character string identifying the profile class.  One of
        ``scnr``, ``mntr``, ``prtr``, ``link``, ``spac``, ``abst``,
        ``nmcl`` (see 7.2.5 of ICC.1:2010 for details).

    .. py:attribute:: xcolor_space
        :type: str

        4-character string (padded with whitespace) identifying the color
        space, e.g. ``XYZ␣``, ``RGB␣`` or ``CMYK`` (see 7.2.6 of
        ICC.1:2010 for details).

    .. py:attribute:: connection_space
        :type: str

        4-character string (padded with whitespace) identifying the color
        space on the B-side of the transform (see 7.2.7 of ICC.1:2010 for
        details).

    .. py:attribute:: header_flags
        :type: int

        The encoded header flags of the profile (see 7.2.11 of ICC.1:2010
        for details).

    .. py:attribute:: header_manufacturer
        :type: str

        4-character string (padded with whitespace) identifying the device
        manufacturer, which shall match the signature contained in the
        appropriate section of the ICC signature registry found at
        www.color.org (see 7.2.12 of ICC.1:2010).

    .. py:attribute:: header_model
        :type: str

        4-character string (padded with whitespace) identifying the device
        model, which shall match the signature contained in the
        appropriate section of the ICC signature registry found at
        www.color.org (see 7.2.13 of ICC.1:2010).

    .. py:attribute:: attributes
        :type: int

        Flags used to identify attributes unique to the particular device
        setup for which the profile is applicable (see 7.2.14 of
        ICC.1:2010 for details).

    .. py:attribute:: rendering_intent
        :type: int

        The rendering intent to use when combining this profile with
        another profile (usually overridden at run-time, but provided here
        for DeviceLink and embedded source profiles, see 7.2.15 of ICC.1:2010).

        One of ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``, ``ImageCms.Intent.PERCEPTUAL``,
        ``ImageCms.Intent.RELATIVE_COLORIMETRIC`` and ``ImageCms.Intent.SATURATION``.

    .. py:attribute:: profile_id
        :type: bytes

        A sequence of 16 bytes identifying the profile (via a specially
        constructed MD5 sum), or 16 binary zeroes if the profile ID has
        not been calculated (see 7.2.18 of ICC.1:2010).

    .. py:attribute:: copyright
        :type: str | None

        The text copyright information for the profile (see 9.2.21 of ICC.1:2010).

    .. py:attribute:: manufacturer
        :type: str | None

        The (English) display string for the device manufacturer (see
        9.2.22 of ICC.1:2010).

    .. py:attribute:: model
        :type: str | None

        The (English) display string for the device model of the device
        for which this profile is created (see 9.2.23 of ICC.1:2010).

    .. py:attribute:: profile_description
        :type: str | None

        The (English) display string for the profile description (see
        9.2.41 of ICC.1:2010).

    .. py:attribute:: target
        :type: str | None

        The name of the registered characterization data set, or the
        measurement data for a characterization target (see 9.2.14 of
        ICC.1:2010).

    .. py:attribute:: red_colorant
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The first column in the matrix used in matrix/TRC transforms (see 9.2.44 of ICC.1:2010).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: green_colorant
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The second column in the matrix used in matrix/TRC transforms (see 9.2.30 of ICC.1:2010).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: blue_colorant
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The third column in the matrix used in matrix/TRC transforms (see 9.2.4 of ICC.1:2010).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: luminance
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The absolute luminance of emissive devices in candelas per square
        metre as described by the Y channel (see 9.2.32 of ICC.1:2010).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: chromaticity
        :type: tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]] | None

        The data of the phosphor/colorant chromaticity set used (red,
        green and blue channels, see 9.2.16 of ICC.1:2010).

        The value is in the format ``((x, y, Y), (x, y, Y), (x, y, Y))``, if available.

    .. py:attribute:: chromatic_adaptation
        :type: tuple[tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]], tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]]] | None

        The chromatic adaptation matrix converts a color measured using the
        actual illumination conditions and relative to the actual adopted
        white, to a color relative to the PCS adopted white, with
        complete adaptation from the actual adopted white chromaticity to
        the PCS adopted white chromaticity (see 9.2.15 of ICC.1:2010).

        Two 3-tuples of floats are returned in a 2-tuple,
        one in (X, Y, Z) space and one in (x, y, Y) space.

    .. py:attribute:: colorant_table
        :type: list[str]

        This tag identifies the colorants used in the profile by a unique
        name and set of PCSXYZ or PCSLAB values (see 9.2.19 of
        ICC.1:2010).

    .. py:attribute:: colorant_table_out
        :type: list[str]

        This tag identifies the colorants used in the profile by a unique
        name and set of PCSLAB values (for DeviceLink profiles only, see
        9.2.19 of ICC.1:2010).

    .. py:attribute:: colorimetric_intent
        :type: str | None

        4-character string (padded with whitespace) identifying the image
        state of PCS colorimetry produced using the colorimetric intent
        transforms (see 9.2.20 of ICC.1:2010 for details).

    .. py:attribute:: perceptual_rendering_intent_gamut
        :type: str | None

        4-character string (padded with whitespace) identifying the (one)
        standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
        details).

    .. py:attribute:: saturation_rendering_intent_gamut
        :type: str | None

        4-character string (padded with whitespace) identifying the (one)
        standard reference medium gamut (see 9.2.37 of ICC.1:2010 for
        details).

    .. py:attribute:: technology
        :type: str | None

        4-character string (padded with whitespace) identifying the device
        technology (see 9.2.47 of ICC.1:2010 for details).

    .. py:attribute:: media_black_point
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        This tag specifies the media black point and is used for
        generating absolute colorimetry.

        This tag was available in ICC 3.2, but it is removed from
        version 4.

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: media_white_point
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        This tag specifies the media white point and is used for
        generating absolute colorimetry.

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: media_white_point_temperature
        :type: float | None

        Calculates the white point temperature (see the LCMS documentation
        for more information).

    .. py:attribute:: viewing_condition
        :type: str | None

        The (English) display string for the viewing conditions (see
        9.2.48 of ICC.1:2010).

    .. py:attribute:: screening_description
        :type: str | None

        The (English) display string for the screening conditions.

        This tag was available in ICC 3.2, but it is removed from
        version 4.

    .. py:attribute:: red_primary
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The XYZ-transform of the RGB primary color red (1, 0, 0).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: green_primary
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The XYZ-transform of the RGB primary color green (0, 1, 0).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: blue_primary
        :type: tuple[tuple[float, float, float], tuple[float, float, float]] | None

        The XYZ-transform of the RGB primary color blue (0, 0, 1).

        The value is in the format ``((X, Y, Z), (x, y, Y))``, if available.

    .. py:attribute:: is_matrix_shaper
        :type: bool

        True if this profile is implemented as a matrix shaper (see
        documentation on LCMS).

    .. py:attribute:: clut
        :type: dict[int, tuple[bool, bool, bool]] | None

        Returns a dictionary of all supported intents and directions for
        the CLUT model.

        The dictionary is indexed by intents
        (``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``,
        ``ImageCms.Intent.PERCEPTUAL``,
        ``ImageCms.Intent.RELATIVE_COLORIMETRIC`` and
        ``ImageCms.Intent.SATURATION``).

        The values are 3-tuples indexed by directions
        (``ImageCms.Direction.INPUT``, ``ImageCms.Direction.OUTPUT``,
        ``ImageCms.Direction.PROOF``).

        The elements of the tuple are booleans.  If the value is ``True``,
        that intent is supported for that direction.

    .. py:attribute:: intent_supported
        :type: dict[int, tuple[bool, bool, bool]] | None

        Returns a dictionary of all supported intents and directions.

        The dictionary is indexed by intents
        (``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``,
        ``ImageCms.Intent.PERCEPTUAL``,
        ``ImageCms.Intent.RELATIVE_COLORIMETRIC`` and
        ``ImageCms.Intent.SATURATION``).

        The values are 3-tuples indexed by directions
        (``ImageCms.Direction.INPUT``, ``ImageCms.Direction.OUTPUT``,
        ``ImageCms.Direction.PROOF``).

        The elements of the tuple are booleans.  If the value is ``True``,
        that intent is supported for that direction.

    There is one function defined on the class:

    .. py:method:: is_intent_supported(intent: int, direction: int, /)

        Returns if the intent is supported for the given direction.

        Note that you can also get this information for all intents and directions
        with :py:attr:`.intent_supported`.

        :param intent: One of ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``,
               ``ImageCms.Intent.PERCEPTUAL``,
               ``ImageCms.Intent.RELATIVE_COLORIMETRIC``
               and ``ImageCms.Intent.SATURATION``.
        :param direction: One of ``ImageCms.Direction.INPUT``,
                  ``ImageCms.Direction.OUTPUT``
                  and ``ImageCms.Direction.PROOF``
        :return: Boolean if the intent and direction is supported.

---

### Reference ImageColor (`docs/reference/ImageColor.rst`)

.. py:module:: PIL.ImageColor
.. py:currentmodule:: PIL.ImageColor

:py:mod:`~PIL.ImageColor` module
================================

The :py:mod:`~PIL.ImageColor` module contains color tables and converters from
CSS3-style color specifiers to RGB tuples. This module is used by
:py:meth:`PIL.Image.new` and the :py:mod:`~PIL.ImageDraw` module, among
others.

.. _color-names:

Color names
-----------

The ImageColor module supports the following string formats:

* Hexadecimal color specifiers, given as ``#rgb``, ``#rgba``, ``#rrggbb`` or
  ``#rrggbbaa``, where ``r`` is red, ``g`` is green, ``b`` is blue and ``a`` is
  alpha (also called 'opacity'). For example, ``#ff0000`` specifies pure red,
  and ``#ff0000cc`` specifies red with 80% opacity (``cc`` is 204 in decimal
  form, and 204 / 255 = 0.8).

* RGB functions, given as ``rgb(red, green, blue)`` where the color values are
  integers in the range 0 to 255. Alternatively, the color values can be given
  as three percentages (0% to 100%). For example, ``rgb(255,0,0)`` and
  ``rgb(100%,0%,0%)`` both specify pure red.

* RGBA functions, given as ``rgba(red, green, blue, alpha)`` where the color
  values and the alpha value are integers in the range 0 to 255. For example,
  ``rgba(255,0,0,128)`` specifies pure red with 50% opacity.

* Hue-Saturation-Lightness (HSL) functions, given as ``hsl(hue, saturation%,
  lightness%)`` where hue is the color given as an angle between 0 and 360
  (red=0, green=120, blue=240), saturation is a value between 0% and 100%
  (gray=0%, full color=100%), and lightness is a value between 0% and 100%
  (black=0%, normal=50%, white=100%). For example, ``hsl(0,100%,50%)`` is pure
  red.

* Hue-Saturation-Value (HSV) functions, given as ``hsv(hue, saturation%,
  value%)`` where hue and saturation are the same as HSL, and value is between
  0% and 100% (black=0%, normal=100%). For example, ``hsv(0,100%,100%)`` is
  pure red. This format is also known as Hue-Saturation-Brightness (HSB), and
  can be given as ``hsb(hue, saturation%, brightness%)``, where each of the
  values are used as they are in HSV.

* Common HTML color names. The :py:mod:`~PIL.ImageColor` module provides some
  140 standard color names, based on the colors supported by the X Window
  system and most web browsers. Color names are case insensitive. For example,
  ``red`` and ``Red`` both specify pure red.

Functions
---------

.. py:function:: getrgb(color)

    Convert a color string to an RGB tuple. If the string cannot be parsed,
    this function raises a :py:exc:`ValueError` exception.

    .. versionadded:: 1.1.4

.. py:function:: getcolor(color, mode)

    Same as :py:func:`~PIL.ImageColor.getrgb`, but converts the RGB value to a
    grayscale value if the mode is not color or a palette image. If the string
    cannot be parsed, this function raises a :py:exc:`ValueError` exception.

    .. versionadded:: 1.1.4

---

### Reference ImageDraw (`docs/reference/ImageDraw.rst`)

.. py:module:: PIL.ImageDraw
.. py:currentmodule:: PIL.ImageDraw

:py:mod:`~PIL.ImageDraw` module
===============================

The :py:mod:`~PIL.ImageDraw` module provides simple 2D graphics for
:py:class:`~PIL.Image.Image` objects.  You can use this module to create new
images, annotate or retouch existing images, and to generate graphics on the
fly for web use.

For a more advanced drawing library for PIL, see the `aggdraw module`_.

.. _aggdraw module: https://github.com/pytroll/aggdraw

Example: Draw a gray cross over an image
----------------------------------------

::

    import sys
    from PIL import Image, ImageDraw

    with Image.open("hopper.jpg") as im:

        draw = ImageDraw.Draw(im)
        draw.line((0, 0) + im.size, fill=128)
        draw.line((0, im.size[1], im.size[0], 0), fill=128)

        # write to stdout
        im.save(sys.stdout, "PNG")


Concepts
--------

Coordinates
^^^^^^^^^^^

The graphics interface uses the same coordinate system as PIL itself, with (0,
0) in the upper left corner. Any pixels drawn outside of the image bounds will
be discarded.

Colors
^^^^^^

To specify colors, you can use numbers or tuples just as you would use with
:py:meth:`PIL.Image.new`. See :ref:`colors` for more information.

For palette images (mode “P”), use integers as color indexes. In 1.1.4 and
later, you can also use RGB 3-tuples or color names (see below). The drawing
layer will automatically assign color indexes, as long as you don’t draw with
more than 256 colors.

Color names
^^^^^^^^^^^

See :ref:`color-names` for the color names supported by Pillow.

Alpha channel
^^^^^^^^^^^^^

By default, when drawing onto an existing image, the image's pixel values are simply
replaced by the new color::

    im = Image.new("RGBA", (1, 1), (255, 0, 0))
    d = ImageDraw.Draw(im)
    d.rectangle((0, 0, 1, 1), (0, 255, 0, 127))
    assert im.getpixel((0, 0)) == (0, 255, 0, 127)

    # Alpha channel values have no effect when drawing with RGB mode
    im = Image.new("RGB", (1, 1), (255, 0, 0))
    d = ImageDraw.Draw(im)
    d.rectangle((0, 0, 1, 1), (0, 255, 0, 127))
    assert im.getpixel((0, 0)) == (0, 255, 0)

If you would like to combine translucent color with an RGB image, then initialize the
ImageDraw instance with the RGBA mode::

    from PIL import Image, ImageDraw
    im = Image.new("RGB", (1, 1), (255, 0, 0))
    d = ImageDraw.Draw(im, "RGBA")
    d.rectangle((0, 0, 1, 1), (0, 255, 0, 127))
    assert im.getpixel((0, 0)) == (128, 127, 0)

If you would like to combine translucent color with an RGBA image underneath, you will
need to combine multiple images::

    from PIL import Image, ImageDraw
    im = Image.new("RGBA", (1, 1), (255, 0, 0, 255))
    im2 = Image.new("RGBA", (1, 1))
    d = ImageDraw.Draw(im2)
    d.rectangle((0, 0, 1, 1), (0, 255, 0, 127))
    im.paste(im2.convert("RGB"), mask=im2)
    assert im.getpixel((0, 0)) == (128, 127, 0, 255)

Fonts
^^^^^

PIL can use bitmap fonts or OpenType/TrueType fonts.

Bitmap fonts are stored in PIL's own format, where each font typically consists
of two files, one named .pil and the other usually named .pbm. The former
contains font metrics, the latter raster data.

To load a bitmap font, use the load functions in the :py:mod:`~PIL.ImageFont`
module.

To load an OpenType/TrueType font, use the truetype function in the
:py:mod:`~PIL.ImageFont` module. Note that this function depends on third-party
libraries, and may not be available in all PIL builds.

Example: Draw partial opacity text
----------------------------------

::

    from PIL import Image, ImageDraw, ImageFont

    # get an image
    with Image.open("Pillow/Tests/images/hopper.png").convert("RGBA") as base:

        # make a blank image for the text, initialized to transparent text color
        txt = Image.new("RGBA", base.size, (255, 255, 255, 0))

        # get a font
        fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
        # get a drawing context
        d = ImageDraw.Draw(txt)

        # draw text, half opacity
        d.text((10, 10), "Hello", font=fnt, fill=(255, 255, 255, 128))
        # draw text, full opacity
        d.text((10, 60), "World", font=fnt, fill=(255, 255, 255, 255))

        out = Image.alpha_composite(base, txt)

        out.show()

Example: Draw multiline text
----------------------------

::

    from PIL import Image, ImageDraw, ImageFont

    # create an image
    out = Image.new("RGB", (150, 100), (255, 255, 255))

    # get a font
    fnt = ImageFont.truetype("Pillow/Tests/fonts/FreeMono.ttf", 40)
    # get a drawing context
    d = ImageDraw.Draw(out)

    # draw multiline text
    d.multiline_text((10, 10), "Hello\nWorld", font=fnt, fill=(0, 0, 0))

    out.show()


Functions
---------

.. py:method:: Draw(im, mode=None)

    Creates an object that can be used to draw in the given image.

    Note that the image will be modified in place.

    :param im: The image to draw in.
    :param mode: Optional mode to use for color values.  For RGB
        images, this argument can be RGB or RGBA (to blend the
        drawing into the image).  For all other modes, this argument
        must be the same as the image mode.  If omitted, the mode
        defaults to the mode of the image.

Attributes
----------

.. py:attribute:: ImageDraw.fill
    :type: bool
    :value: False

    Selects whether :py:attr:`ImageDraw.ink` should be used as a fill or outline color.

.. py:attribute:: ImageDraw.font

    The current default font.

    Can be set per instance::

        from PIL import ImageDraw, ImageFont
        draw = ImageDraw.Draw(image)
        draw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

    Or globally for all future ImageDraw instances::

        from PIL import ImageDraw, ImageFont
        ImageDraw.ImageDraw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf")

.. py:attribute:: ImageDraw.fontmode

    The current font drawing mode.

    Set to ``"1"`` to disable antialiasing or ``"L"`` to enable it.

.. py:attribute:: ImageDraw.ink
    :type: int

    The internal representation of the current default color.

Methods
-------

.. py:method:: ImageDraw.getfont()

    Get the current default font, :py:attr:`ImageDraw.font`.

    If the current default font is ``None``,
    it is initialized with :py:func:`.ImageFont.load_default`.

    :returns: An image font.

.. py:method:: ImageDraw.arc(xy, start, end, fill=None, width=1)

    Draws an arc (a portion of a circle outline) between the start and end
    angles, inside the given bounding box.

    :param xy: Two points to define the bounding box. Sequence of ``[(x0, y0),
        (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0`` and ``y1 >=
        y0``.
    :param start: Starting angle, in degrees. Angles are measured from 3
        o'clock, increasing clockwise.
    :param end: Ending angle, in degrees.
    :param fill: Color to use for the arc.
    :param width: The line width, in pixels.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.bitmap(xy, bitmap, fill=None)

    Draws a bitmap (mask) at the given position, using the current fill color
    for the non-zero portions. The bitmap should be a valid transparency mask
    (mode “1”) or matte (mode “L” or “RGBA”).

    This is equivalent to doing ``image.paste(xy, color, bitmap)``.

    To paste pixel data into an image, use the
    :py:meth:`~PIL.Image.Image.paste` method on the image itself.

.. py:method:: ImageDraw.chord(xy, start, end, fill=None, outline=None, width=1)

    Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points
    with a straight line.

    :param xy: Two points to define the bounding box. Sequence of ``[(x0, y0),
        (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0`` and ``y1 >=
        y0``.
    :param outline: Color to use for the outline.
    :param fill: Color to use for the fill.
    :param width: The line width, in pixels.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.circle(xy, radius, fill=None, outline=None, width=1)

    Draws a circle with a given radius centering on a point.

    .. versionadded:: 10.4.0

    :param xy: The point for the center of the circle, e.g. ``(x, y)``.
    :param radius: Radius of the circle.
    :param outline: Color to use for the outline.
    :param fill: Color to use for the fill.
    :param width: The line width, in pixels.

.. py:method:: ImageDraw.ellipse(xy, fill=None, outline=None, width=1)

    Draws an ellipse inside the given bounding box.

    :param xy: Two points to define the bounding box. Sequence of either
        ``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0``
        and ``y1 >= y0``.
    :param outline: Color to use for the outline.
    :param fill: Color to use for the fill.
    :param width: The line width, in pixels.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.line(xy, fill=None, width=1, joint=None)

    Draws a line between the coordinates in the ``xy`` list.
    The coordinate pixels are included in the drawn line.

    :param xy: Sequence of either 2-tuples like ``[(x, y), (x, y), ...]`` or
               numeric values like ``[x, y, x, y, ...]``.
    :param fill: Color to use for the line.
    :param width: The line width, in pixels.

        .. versionadded:: 1.1.5

        .. note:: This option was broken until version 1.1.6.
    :param joint: Joint type between a sequence of lines. It can be ``"curve"``, for rounded edges, or :data:`None`.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=1)

    Same as arc, but also draws straight lines between the end points and the
    center of the bounding box.

    :param xy: Two points to define the bounding box. Sequence of ``[(x0, y0),
        (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0`` and ``y1 >=
        y0``.
    :param start: Starting angle, in degrees. Angles are measured from 3
        o'clock, increasing clockwise.
    :param end: Ending angle, in degrees.
    :param fill: Color to use for the fill.
    :param outline: Color to use for the outline.
    :param width: The line width, in pixels.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.point(xy, fill=None)

    Draws points (individual pixels) at the given coordinates.

    :param xy: Sequence of either 2-tuples like ``[(x, y), (x, y), ...]`` or
               numeric values like ``[x, y, x, y, ...]``.
    :param fill: Color to use for the point.

.. py:method:: ImageDraw.polygon(xy, fill=None, outline=None, width=1)

    Draws a polygon.

    The polygon outline consists of straight lines between the given
    coordinates, plus a straight line between the last and the first
    coordinate. The coordinate pixels are included in the drawn polygon.

    :param xy: Sequence of either 2-tuples like ``[(x, y), (x, y), ...]`` or
               numeric values like ``[x, y, x, y, ...]``.
    :param fill: Color to use for the fill.
    :param outline: Color to use for the outline.
    :param width: The line width, in pixels.


.. py:method:: ImageDraw.regular_polygon(bounding_circle, n_sides, rotation=0, fill=None, outline=None, width=1)

    Draws a regular polygon inscribed in ``bounding_circle``,
    with ``n_sides``, and rotation of ``rotation`` degrees.

    :param bounding_circle: The bounding circle is a tuple defined
        by a point and radius.
        (e.g. ``bounding_circle=(x, y, r)`` or ``((x, y), r)``).
        The polygon is inscribed in this circle.
    :param n_sides: Number of sides
        (e.g. ``n_sides=3`` for a triangle, ``6`` for a hexagon).
    :param rotation: Apply an arbitrary rotation to the polygon
        (e.g. ``rotation=90``, applies a 90 degree rotation).
    :param fill: Color to use for the fill.
    :param outline: Color to use for the outline.
    :param width: The line width, in pixels.


.. py:method:: ImageDraw.rectangle(xy, fill=None, outline=None, width=1)

    Draws a rectangle.

    :param xy: Two points to define the bounding box. Sequence of either
            ``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0`` and
            ``y1 >= y0``. The bounding box is inclusive of both endpoints.
    :param fill: Color to use for the fill.
    :param outline: Color to use for the outline.
    :param width: The line width, in pixels.

        .. versionadded:: 5.3.0

.. py:method:: ImageDraw.rounded_rectangle(xy, radius=0, fill=None, outline=None, width=1, corners=None)

    Draws a rounded rectangle.

    :param xy: Two points to define the bounding box. Sequence of either
            ``[(x0, y0), (x1, y1)]`` or ``[x0, y0, x1, y1]``, where ``x1 >= x0`` and
            ``y1 >= y0``. The bounding box is inclusive of both endpoints.
    :param radius: Radius of the corners, limited to half of the smallest dimension of
            the bounding box.
    :param fill: Color to use for the fill.
    :param outline: Color to use for the outline.
    :param width: The line width, in pixels.
    :param corners: A tuple of whether to round each corner,
                    ``(top_left, top_right, bottom_right, bottom_left)``.
                    Keyword-only argument.

    .. versionadded:: 8.2.0

.. py:method:: ImageDraw.shape(shape, fill=None, outline=None)

    .. warning:: This method is experimental.

    Draw a shape.

.. py:method:: ImageDraw.text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, stroke_fill=None, embedded_color=False, font_size=None)

    Draws the string at the given position.

    :param xy: The anchor coordinates of the text.
    :param text: String to be drawn. If it contains any newline characters,
                 the text is passed on to
                 :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_text`.
    :param fill: Color to use for the text.
    :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance.
    :param anchor: The text anchor alignment. Determines the relative location of
                   the anchor to the text. The default alignment is top left,
                   specifically ``la`` for horizontal text and ``lt`` for
                   vertical text. See :ref:`text-anchors` for details.
                   This parameter is ignored for non-TrueType fonts.

                    .. note:: This parameter was present in earlier versions
                              of Pillow, but implemented only in version 8.0.0.

    :param spacing: If the text is passed on to
                    :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_text`,
                    the number of pixels between lines.
    :param align: If the text is passed on to
                  :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_text`,
                  ``"left"``, ``"center"``, ``"right"`` or ``"justify"``. Determines
                  the relative alignment of lines. Use the ``anchor`` parameter to
                  specify the alignment to ``xy``.

                  .. versionadded:: 11.2.1 ``"justify"``
    :param direction: Direction of the text. It can be ``"rtl"`` (right to
                      left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom).
                      Requires libraqm.

                      .. versionadded:: 4.2.0

    :param features: A list of OpenType font features to be used during text
                     layout. This is usually used to turn on optional
                     font features that are not enabled by default,
                     for example ``"dlig"`` or ``"ss01"``, but can be also
                     used to turn off default font features, for
                     example ``"-liga"`` to disable ligatures or ``"-kern"``
                     to disable kerning.  To get all supported
                     features, see `OpenType docs`_.
                     Requires libraqm.

                     .. versionadded:: 4.2.0

    :param language: Language of the text. Different languages may use
                     different glyph shapes or ligatures. This parameter tells
                     the font which language the text is in, and to apply the
                     correct substitutions as appropriate, if available.
                     It should be a `BCP 47 language code`_.
                     Requires libraqm.

                     .. versionadded:: 6.0.0

    :param stroke_width: The width of the text stroke.

                     .. versionadded:: 6.2.0

    :param stroke_fill: Color to use for the text stroke. If not given, will default to
        the ``fill`` parameter.

        .. versionadded:: 6.2.0

    :param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).

                    .. versionadded:: 8.0.0

    :param font_size: If ``font`` is not provided, then the size to use for the default
                      font.
                      Keyword-only argument.

                    .. versionadded:: 10.1.0


.. py:method:: ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, stroke_fill=None, embedded_color=False, font_size=None)

    Draws the string at the given position.

    :param xy: The anchor coordinates of the text.
    :param text: String to be drawn.
    :param fill: Color to use for the text.
    :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance.

    :param anchor: The text anchor alignment. Determines the relative location of
                   the anchor to the text. The default alignment is top left,
                   specifically ``la`` for horizontal text and ``lt`` for
                   vertical text. See :ref:`text-anchors` for details.
                   This parameter is ignored for non-TrueType fonts.

                    .. note:: This parameter was present in earlier versions
                              of Pillow, but implemented only in version 8.0.0.

    :param spacing: The number of pixels between lines.
    :param align: ``"left"``, ``"center"``, ``"right"`` or ``"justify"``. Determines
                  the relative alignment of lines. Use the ``anchor`` parameter to
                  specify the alignment to ``xy``.

                  .. versionadded:: 11.2.1 ``"justify"``
    :param direction: Direction of the text. It can be ``"rtl"`` (right to
                      left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom).
                      Requires libraqm.

                      .. versionadded:: 4.2.0

    :param features: A list of OpenType font features to be used during text
                     layout. This is usually used to turn on optional
                     font features that are not enabled by default,
                     for example ``"dlig"`` or ``"ss01"``, but can be also
                     used to turn off default font features, for
                     example ``"-liga"`` to disable ligatures or ``"-kern"``
                     to disable kerning.  To get all supported
                     features, see `OpenType docs`_.
                     Requires libraqm.

                     .. versionadded:: 4.2.0

    :param language: Language of the text. Different languages may use
                     different glyph shapes or ligatures. This parameter tells
                     the font which language the text is in, and to apply the
                     correct substitutions as appropriate, if available.
                     It should be a `BCP 47 language code`_.
                     Requires libraqm.

                     .. versionadded:: 6.0.0

    :param stroke_width: The width of the text stroke.

                     .. versionadded:: 6.2.0

    :param stroke_fill: Color to use for the text stroke. If not given, will default to
                        the ``fill`` parameter.

                     .. versionadded:: 6.2.0

    :param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).

                     .. versionadded:: 8.0.0

    :param font_size: If ``font`` is not provided, then the size to use for the default
                      font.
                      Keyword-only argument.

                    .. versionadded:: 10.1.0

.. py:method:: ImageDraw.textlength(text, font=None, direction=None, features=None, language=None, embedded_color=False, font_size=None)

    Returns length (in pixels with 1/64 precision) of given text when rendered
    in font with provided direction, features, and language.

    This is the amount by which following text should be offset.
    Text bounding box may extend past the length in some fonts,
    e.g. when using italics or accents.

    The result is returned as a float; it is a whole number if using basic layout.

    Note that the sum of two lengths may not equal the length of a concatenated
    string due to kerning. If you need to adjust for kerning, include the following
    character and subtract its length.

    For example, instead of ::

        hello = draw.textlength("Hello", font)
        world = draw.textlength("World", font)
        hello_world = hello + world  # not adjusted for kerning
        assert hello_world == draw.textlength("HelloWorld", font)  # may fail

    use ::

        hello = draw.textlength("HelloW", font) - draw.textlength(
            "W", font
        )  # adjusted for kerning
        world = draw.textlength("World", font)
        hello_world = hello + world  # adjusted for kerning
        assert hello_world == draw.textlength("HelloWorld", font)  # True

    or disable kerning with (requires libraqm) ::

        hello = draw.textlength("Hello", font, features=["-kern"])
        world = draw.textlength("World", font, features=["-kern"])
        hello_world = hello + world  # kerning is disabled, no need to adjust
        assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"])  # True

    .. seealso:: :py:meth:`PIL.ImageText.Text.get_length`

    .. versionadded:: 8.0.0

    :param text: Text to be measured. May not contain any newline characters.
    :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance.
    :param direction: Direction of the text. It can be ``"rtl"`` (right to
                      left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom).
                      Requires libraqm.
    :param features: A list of OpenType font features to be used during text
                     layout. This is usually used to turn on optional
                     font features that are not enabled by default,
                     for example ``"dlig"`` or ``"ss01"``, but can be also
                     used to turn off default font features, for
                     example ``"-liga"`` to disable ligatures or ``"-kern"``
                     to disable kerning.  To get all supported
                     features, see `OpenType docs`_.
                     Requires libraqm.
    :param language: Language of the text. Different languages may use
                     different glyph shapes or ligatures. This parameter tells
                     the font which language the text is in, and to apply the
                     correct substitutions as appropriate, if available.
                     It should be a `BCP 47 language code`_.
                     Requires libraqm.
    :param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).
    :param font_size: If ``font`` is not provided, then the size to use for the default
                      font.
                      Keyword-only argument.

                    .. versionadded:: 10.1.0

    :return: Either width for horizontal text, or height for vertical text.

.. py:method:: ImageDraw.textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, embedded_color=False, font_size=None)

    Returns bounding box (in pixels) of given text relative to given anchor
    when rendered in font with provided direction, features, and language.
    Only supported for TrueType fonts.

    Use :py:meth:`textlength` to get the offset of following text with
    1/64 pixel precision. The bounding box includes extra margins for
    some fonts, e.g. italics or accents.

    .. versionadded:: 8.0.0

    :param xy: The anchor coordinates of the text.
    :param text: Text to be measured. If it contains any newline characters,
                 the text is passed on to
                 :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_textbbox`.
    :param font: A :py:class:`~PIL.ImageFont.FreeTypeFont` instance.
    :param anchor: The text anchor alignment. Determines the relative location of
                   the anchor to the text. The default alignment is top left,
                   specifically ``la`` for horizontal text and ``lt`` for
                   vertical text. See :ref:`text-anchors` for details.
                   This parameter is ignored for non-TrueType fonts.
    :param spacing: If the text is passed on to
                    :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_textbbox`,
                    the number of pixels between lines.
    :param align: If the text is passed on to
                  :py:meth:`~PIL.ImageDraw.ImageDraw.multiline_textbbox`,
                  ``"left"``, ``"center"``, ``"right"`` or ``"justify"``. Determines
                  the relative alignment of lines. Use the ``anchor`` parameter to
                  specify the alignment to ``xy``.

                  .. versionadded:: 11.2.1 ``"justify"``
    :param direction: Direction of the text. It can be ``"rtl"`` (right to
                      left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom).
                      Requires libraqm.
    :param features: A list of OpenType font features to be used during text
                     layout. This is usually used to turn on optional
                     font features that are not enabled by default,
                     for example ``"dlig"`` or ``"ss01"``, but can be also
                     used to turn off default font features, for
                     example ``"-liga"`` to disable ligatures or ``"-kern"``
                     to disable kerning.  To get all supported
                     features, see `OpenType docs`_.
                     Requires libraqm.
    :param language: Language of the text. Different languages may use
                     different glyph shapes or ligatures. This parameter tells
                     the font which language the text is in, and to apply the
                     correct substitutions as appropriate, if available.
                     It should be a `BCP 47 language code`_.
                     Requires libraqm.
    :param stroke_width: The width of the text stroke.
    :param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).
    :param font_size: If ``font`` is not provided, then the size to use for the default
                      font.
                      Keyword-only argument.

                    .. versionadded:: 10.1.0

    :return: ``(left, top, right, bottom)`` bounding box

.. py:method:: ImageDraw.multiline_textbbox(xy, text, font=None, anchor=None, spacing=4, align="left", direction=None, features=None, language=None, stroke_width=0, embedded_color=False, font_size=None)

    Returns bounding box (in pixels) of given text relative to given anchor
    when rendered in font with provided direction, features, and language.
    Only supported for TrueType fonts.

    Use :py:meth:`textlength` to get the offset of following text with
    1/64 pixel precision. The bounding box includes extra margins for
    some fonts, e.g. italics or accents.

    .. seealso:: :py:meth:`PIL.ImageText.Text.get_bbox`

    .. versionadded:: 8.0.0

    :param xy: The anchor coordinates of the text.
    :param text: Text to be measured.
    :param font: A :py:class:`~PIL.ImageFont.FreeTypeFont` instance.
    :param anchor: The text anchor alignment. Determines the relative location of
                   the anchor to the text. The default alignment is top left,
                   specifically ``la`` for horizontal text and ``lt`` for
                   vertical text. See :ref:`text-anchors` for details.
                   This parameter is ignored for non-TrueType fonts.
    :param spacing: The number of pixels between lines.
    :param align: ``"left"``, ``"center"``, ``"right"`` or ``"justify"``. Determines
                  the relative alignment of lines. Use the ``anchor`` parameter to
                  specify the alignment to ``xy``.

                  .. versionadded:: 11.2.1 ``"justify"``
    :param direction: Direction of the text. It can be ``"rtl"`` (right to
                      left), ``"ltr"`` (left to right) or ``"ttb"`` (top to bottom).
                      Requires libraqm.
    :param features: A list of OpenType font features to be used during text
                     layout. This is usually used to turn on optional
                     font features that are not enabled by default,
                     for example ``"dlig"`` or ``"ss01"``, but can be also
                     used to turn off default font features, for
                     example ``"-liga"`` to disable ligatures or ``"-kern"``
                     to disable kerning.  To get all supported
                     features, see `OpenType docs`_.
                     Requires libraqm.
    :param language: Language of the text. Different languages may use
                     different glyph shapes or ligatures. This parameter tells
                     the font which language the text is in, and to apply the
                     correct substitutions as appropriate, if available.
                     It should be a `BCP 47 language code`_.
                     Requires libraqm.
    :param stroke_width: The width of the text stroke.
    :param embedded_color: Whether to use font embedded color glyphs (COLR, CBDT, SBIX).
    :param font_size: If ``font`` is not provided, then the size to use for the default
                      font.
                      Keyword-only argument.

                    .. versionadded:: 10.1.0

    :return: ``(left, top, right, bottom)`` bounding box

.. py:method:: getdraw(im=None)

    .. warning:: This method is experimental.

    A more advanced 2D drawing interface for PIL images,
    based on the WCK interface.

    :param im: The image to draw in.
    :returns: A (drawing context, drawing resource factory) tuple.

.. autofunction:: PIL.ImageDraw.floodfill

.. _BCP 47 language code: https://www.w3.org/International/articles/language-tags/
.. _OpenType docs: https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist

---

### Reference ImageEnhance (`docs/reference/ImageEnhance.rst`)

.. py:module:: PIL.ImageEnhance
.. py:currentmodule:: PIL.ImageEnhance

:py:mod:`~PIL.ImageEnhance` module
==================================

The :py:mod:`~PIL.ImageEnhance` module contains a number of classes that can be used
for image enhancement.

Example: Vary the sharpness of an image
---------------------------------------

::

    from PIL import ImageEnhance

    enhancer = ImageEnhance.Sharpness(image)

    for i in range(8):
        factor = i / 4.0
        enhancer.enhance(factor).show(f"Sharpness {factor:f}")

Also see the :file:`enhancer.py` demo program in the :file:`Scripts/`
directory.

Classes
-------

All enhancement classes implement a common interface, containing a single
method:

.. _enhancement-factor:

.. py:class:: _Enhance

    .. py:method:: enhance(factor)

        Returns an enhanced image.

        :param factor: A floating point value controlling the enhancement.
                       Factor 1.0 always returns a copy of the original image,
                       lower factors mean less color (brightness, contrast,
                       etc), and higher values more. There are no restrictions
                       on this value.

.. py:class:: Color(image)

    Adjust image color balance.

    This class can be used to adjust the colour balance of an image, in a
    manner similar to the controls on a colour TV set. An
    :ref:`enhancement factor <enhancement-factor>` of 0.0 gives a black and
    white image. A factor of 1.0 gives the original image.

.. py:class:: Contrast(image)

    Adjust image contrast.

    This class can be used to control the contrast of an image, similar to the
    contrast control on a TV set. An
    :ref:`enhancement factor <enhancement-factor>` of 0.0 gives a solid gray
    image, a factor of 1.0 gives the original image, and greater values
    increase the contrast of the image.

.. py:class:: Brightness(image)

    Adjust image brightness.

    This class can be used to control the brightness of an image. An
    :ref:`enhancement factor <enhancement-factor>` of 0.0 gives a black image,
    a factor of 1.0 gives the original image, and greater values increase the
    brightness of the image.

.. py:class:: Sharpness(image)

    Adjust image sharpness.

    This class can be used to adjust the sharpness of an image. An
    :ref:`enhancement factor <enhancement-factor>` of 0.0 gives a blurred
    image, a factor of 1.0 gives the original image, and a factor of 2.0 gives
    a sharpened image.

---

### Reference ImageFile (`docs/reference/ImageFile.rst`)

.. py:module:: PIL.ImageFile
.. py:currentmodule:: PIL.ImageFile

:py:mod:`~PIL.ImageFile` module
===============================

The :py:mod:`~PIL.ImageFile` module provides support functions for the image open
and save functions.

In addition, it provides a :py:class:`Parser` class which can be used to decode
an image piece by piece (e.g. while receiving it over a network connection).
This class implements the same consumer interface as the standard **sgmllib**
and **xmllib** modules.

Example: Parse an image
-----------------------

::

    from PIL import ImageFile

    fp = open("hopper.ppm", "rb")

    p = ImageFile.Parser()

    while 1:
        s = fp.read(1024)
        if not s:
            break
        p.feed(s)

    im = p.close()

    im.save("copy.jpg")


Classes
-------

.. autoclass:: PIL.ImageFile._Tile()
    :member-order: bysource
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFile.Parser()
    :members:

.. autoclass:: PIL.ImageFile.PyCodec()
    :members:

.. autoclass:: PIL.ImageFile.PyDecoder()
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFile.PyEncoder()
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFile.ImageFile()
    :member-order: bysource
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: PIL.ImageFile.StubHandler()
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFile.StubImageFile()
    :members:
    :show-inheritance:

Constants
---------

.. autodata:: PIL.ImageFile.LOAD_TRUNCATED_IMAGES
.. autodata:: PIL.ImageFile.MAXBLOCK
.. autodata:: PIL.ImageFile.ERRORS
    :annotation:

---

### Reference ImageFilter (`docs/reference/ImageFilter.rst`)

.. py:module:: PIL.ImageFilter
.. py:currentmodule:: PIL.ImageFilter

:py:mod:`~PIL.ImageFilter` module
=================================

The :py:mod:`~PIL.ImageFilter` module contains definitions for a pre-defined set of
filters, which can be used with the :py:meth:`Image.filter()
<PIL.Image.Image.filter>` method.

Example: Filter an image
------------------------

::

    from PIL import ImageFilter

    im1 = im.filter(ImageFilter.BLUR)

    im2 = im.filter(ImageFilter.MinFilter(3))
    im3 = im.filter(ImageFilter.MinFilter)  # same as MinFilter(3)

Filters
-------

Pillow provides the following set of predefined image enhancement filters:

* **BLUR**
* **CONTOUR**
* **DETAIL**
* **EDGE_ENHANCE**
* **EDGE_ENHANCE_MORE**
* **EMBOSS**
* **FIND_EDGES**
* **SHARPEN**
* **SMOOTH**
* **SMOOTH_MORE**

.. autoclass:: PIL.ImageFilter.Color3DLUT
    :members:

.. autoclass:: PIL.ImageFilter.BoxBlur
    :members:

.. autoclass:: PIL.ImageFilter.GaussianBlur
    :members:

.. autoclass:: PIL.ImageFilter.UnsharpMask
    :members:

.. autoclass:: PIL.ImageFilter.Kernel
    :members:

.. autoclass:: PIL.ImageFilter.RankFilter
    :members:

.. autoclass:: PIL.ImageFilter.MedianFilter
    :members:

.. autoclass:: PIL.ImageFilter.MinFilter
    :members:

.. autoclass:: PIL.ImageFilter.MaxFilter
    :members:

.. autoclass:: PIL.ImageFilter.ModeFilter
    :members:

.. class:: Filter

    An abstract mixin used for filtering images
    (for use with :py:meth:`~PIL.Image.Image.filter`).

    Implementors must provide the following method:

    .. method:: filter(self, image)

        Applies a filter to a single-band image, or a single band of an image.

        :returns: A filtered copy of the image.

.. class:: MultibandFilter

    An abstract mixin used for filtering multi-band images
    (for use with :py:meth:`~PIL.Image.Image.filter`).

    Implementors must provide the following method:

    .. method:: filter(self, image)

        Applies a filter to a multi-band image.

        :returns: A filtered copy of the image.

---

### Reference ImageFont (`docs/reference/ImageFont.rst`)

.. py:module:: PIL.ImageFont
.. py:currentmodule:: PIL.ImageFont

:py:mod:`~PIL.ImageFont` module
===============================

The :py:mod:`~PIL.ImageFont` module defines a class with the same name. Instances of
this class store bitmap fonts, and are used with the
:py:meth:`PIL.ImageDraw.ImageDraw.text` method or the :py:class:`PIL.ImageText.Text`
class.

Pillow uses its own font file format to store bitmap fonts, limited to 256 characters. You
can use :py:meth:`~PIL.FontFile.FontFile.to_imagefont` to convert BDF and PCF font
descriptors (X Window font formats) to this format::

    from PIL import PcfFontFile
    with open("Tests/fonts/10x20-ISO8859-1.pcf", "rb") as fp:
        font = PcfFontFile.PcfFontFile(fp)
        imagefont = font.to_imagefont()

Starting with version 1.1.4, PIL can be configured to support TrueType and
OpenType fonts (as well as other font formats supported by the FreeType
library). For earlier versions, TrueType support is only available as part of
the imToolkit package.

When measuring text sizes, this module will not break at newline characters. For
multiline text, see the :py:mod:`~PIL.ImageDraw` module.

.. warning::
    To protect against potential DOS attacks when using arbitrary strings as
    text input, Pillow will raise a :py:exc:`ValueError` if the number of characters
    is over a certain limit, :py:data:`MAX_STRING_LENGTH`.

    This threshold can be changed by setting
    :py:data:`MAX_STRING_LENGTH`. It can be disabled by setting
    ``ImageFont.MAX_STRING_LENGTH = None``.

Example
-------

::

    from PIL import ImageFont, ImageDraw

    draw = ImageDraw.Draw(image)

    # use a bitmap font
    font = ImageFont.load("arial.pil")

    draw.text((10, 10), "hello", font=font)

    # use a truetype font
    font = ImageFont.truetype("arial.ttf", 15)

    draw.text((10, 25), "world", font=font)

Functions
---------

.. autofunction:: PIL.ImageFont.load
.. autofunction:: PIL.ImageFont.load_path
.. autofunction:: PIL.ImageFont.truetype
.. autofunction:: PIL.ImageFont.load_default
.. autofunction:: PIL.ImageFont.load_default_imagefont

Methods
-------

.. autoclass:: PIL.ImageFont.BaseImageFont
    :members:

.. autoclass:: PIL.ImageFont.ImageFont
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFont.FreeTypeFont
    :members:
    :show-inheritance:

.. autoclass:: PIL.ImageFont.TransposedFont
    :members:
    :undoc-members:
    :show-inheritance:

Constants
---------

.. class:: Layout

    .. py:attribute:: BASIC

        Use basic text layout for TrueType font.
        Advanced features such as text direction are not supported.

    .. py:attribute:: RAQM

        Use Raqm text layout for TrueType font.
        Advanced features are supported.

        Requires Raqm, you can check support using
        :py:func:`PIL.features.check_feature` with ``feature="raqm"``.

.. data:: MAX_STRING_LENGTH

    Set to 1,000,000, to protect against potential DOS attacks. Pillow will
    raise a :py:exc:`ValueError` if the number of characters is over this limit. The
    check can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.

Dictionaries
------------

.. autoclass:: Axis
    :members:
    :undoc-members:
    :show-inheritance:

---

### Reference ImageGrab (`docs/reference/ImageGrab.rst`)

.. py:module:: PIL.ImageGrab
.. py:currentmodule:: PIL.ImageGrab

:py:mod:`~PIL.ImageGrab` module
===============================

The :py:mod:`~PIL.ImageGrab` module can be used to copy the contents of the screen
or the clipboard to a PIL image memory.

.. versionadded:: 1.1.3

.. py:function:: grab(bbox=None, include_layered_windows=False, all_screens=False, xdisplay=None, window=None, scale_down=False)

    Take a snapshot of the screen. The pixels inside the bounding box are returned as
    "RGBA" on macOS, or "RGB" image otherwise. If the bounding box is omitted,
    the entire screen is copied.

    On macOS, it will be at 2x if on a Retina screen. If this is not desired, pass
    ``scale_down=True``.

    On Linux, if ``xdisplay`` is ``None`` and the default X11 display does not return
    a snapshot of the screen, ``gnome-screenshot``, ``grim`` or ``spectacle`` will be
    used as a fallback if they are installed. To disable this behaviour, pass
    ``xdisplay=""`` instead.

    .. versionadded:: 1.1.3 Windows support
    .. versionadded:: 3.0.0 macOS support
    .. versionadded:: 7.1.0 Linux support

    :param bbox: What region to copy. Default is the entire screen.
                 On macOS, this is increased to 2x for Retina screens, so the full
                 width of a Retina screen would be 2880, not 1440.
                 On Windows, the top-left point may be negative if ``all_screens=True``
                 is used.
    :param include_layered_windows: Includes layered windows. Windows OS only.

        .. versionadded:: 6.1.0
    :param all_screens: Capture all monitors. Windows OS only.

        .. versionadded:: 6.2.0

    :param xdisplay:
        X11 Display address. Pass :data:`None` to grab the default system screen. Pass ``""`` to grab the default X11 screen on Windows or macOS.

        You can check X11 support using :py:func:`PIL.features.check_feature` with ``feature="xcb"``.

        .. versionadded:: 7.1.0

    :param window:
        Capture a single window. On Windows, this is a HWND. On macOS, this is a
        CGWindowID.

        .. versionadded:: 11.2.1 Windows support
        .. versionadded:: 12.1.0 macOS support

    :param scale_down: On macOS, Retina screens will provide ``bbox`` images at 2x size by default. This will prevent that, and scale down to 1x.
                       Keyword-only argument.

        .. versionadded:: 12.3.0
    :return: An image

.. py:function:: grabclipboard()

    Take a snapshot of the clipboard image, if any.

    On Linux, ``wl-paste`` or ``xclip`` is required.

    .. versionadded:: 1.1.4 Windows support
    .. versionadded:: 3.3.0 macOS support
    .. versionadded:: 9.4.0 Linux support

    :return: On Windows, an image, a list of filenames,
             or None if the clipboard does not contain image data or filenames.
             Note that if a list is returned, the filenames may not represent image files.

             On macOS, an image,
             or None if the clipboard does not contain image data.

             On Linux, an image.

---

### Reference ImageMath (`docs/reference/ImageMath.rst`)

.. py:module:: PIL.ImageMath
.. py:currentmodule:: PIL.ImageMath

:py:mod:`~PIL.ImageMath` module
===============================

The :py:mod:`~PIL.ImageMath` module can be used to evaluate “image expressions”, that
can take a number of images and generate a result.

:py:mod:`~PIL.ImageMath` only supports single-layer images. To process multi-band
images, use the :py:meth:`~PIL.Image.Image.split` method or :py:func:`~PIL.Image.merge`
function.

Example: Using the :py:mod:`~PIL.ImageMath` module
--------------------------------------------------

::

    from PIL import Image, ImageMath

    with Image.open("image1.jpg") as im1:
        with Image.open("image2.jpg") as im2:
            out = ImageMath.lambda_eval(
              lambda args: args["convert"](args["min"](args["a"], args["b"]), 'L'),
              a=im1,
              b=im2
            )
            out = ImageMath.unsafe_eval(
              "convert(min(a, b), 'L')",
              a=im1,
              b=im2
            )

.. py:function:: lambda_eval(expression, options, **kw)

    Returns the result of an image function.

    :param expression: A function that receives a dictionary.
    :param options: Values to add to the function's dictionary. Note that the names
                    must be valid Python identifiers. Deprecated.
                    You can instead use one or more keyword arguments, as
                    shown in the above example.
    :param \**kw: Values to add to the function's dictionary, mapping image names to
                 Image instances.
    :return: An image, an integer value, a floating point value,
             or a pixel tuple, depending on the expression.

.. py:function:: unsafe_eval(expression, options, **kw)

    Evaluates an image expression.

    .. danger::
        This uses Python's ``eval()`` function to process the expression string,
        and carries the security risks of doing so. It is not
        recommended to process expressions without considering this.
        :py:meth:`lambda_eval` is a more secure alternative.

    :py:mod:`~PIL.ImageMath` only supports single-layer images. To process multi-band
    images, use the :py:meth:`~PIL.Image.Image.split` method or
    :py:func:`~PIL.Image.merge` function.

    :param expression: A string which uses the standard Python expression
                       syntax. In addition to the standard operators, you can
                       also use the functions described below.
    :param options: Values to add to the evaluation context. Note that the names must
                    be valid Python identifiers. Deprecated.
                    You can instead use one or more keyword arguments, as
                    shown in the above example.
    :param \**kw: Values to add to the evaluation context, mapping image names to Image
                 instances.
    :return: An image, an integer value, a floating point value,
             or a pixel tuple, depending on the expression.

Expression syntax
-----------------

* :py:meth:`lambda_eval` expressions are functions that receive a dictionary
  containing images and operators.

* :py:meth:`unsafe_eval` expressions are standard Python expressions,
  but they’re evaluated in a non-standard environment.

.. danger::
  :py:meth:`unsafe_eval` uses Python's ``eval()`` function to process the
  expression string, and carries the security risks of doing so.
  It is not recommended to process expressions without considering this.
  :py:meth:`lambda_eval` is a more secure alternative.

Standard operators
^^^^^^^^^^^^^^^^^^

You can use standard arithmetical operators for addition (+), subtraction (-),
multiplication (*), and division (/).

The module also supports unary minus (-), modulo (%), and power (**) operators.

Note that all operations are done with 32-bit integers or 32-bit floating
point values, as necessary. For example, if you add two 8-bit images, the
result will be a 32-bit integer image. If you add a floating point constant to
an 8-bit image, the result will be a 32-bit floating point image.

You can force conversion using the ``convert()``, ``float()``, and ``int()``
functions described below.

Bitwise operators
^^^^^^^^^^^^^^^^^

The module also provides operations that operate on individual bits. This
includes and (&), or (|), and exclusive or (^). You can also invert (~) all
pixel bits.

Note that the operands are converted to 32-bit signed integers before the
bitwise operation is applied. This means that you’ll get negative values if
you invert an ordinary grayscale image. You can use the and (&) operator to
mask off unwanted bits.

Bitwise operators don’t work on floating point images.

Logical operators
^^^^^^^^^^^^^^^^^

Logical operators like ``and``, ``or``, and ``not`` work
on entire images, rather than individual pixels.

An empty image (all pixels zero) is treated as false. All other images are
treated as true.

Note that ``and`` and ``or`` return the last evaluated operand,
while not always returns a boolean value.

Built-in functions
^^^^^^^^^^^^^^^^^^

These functions are applied to each individual pixel.

.. py:currentmodule:: None

.. py:function:: abs(image)
    :noindex:

    Absolute value.

.. py:function:: convert(image, mode)
    :noindex:

    Convert image to the given mode. The mode must be given as a string
    constant.

.. py:function:: float(image)
    :noindex:

    Convert image to 32-bit floating point. This is equivalent to
    convert(image, “F”).

.. py:function:: int(image)
    :noindex:

    Convert image to 32-bit integer. This is equivalent to convert(image, “I”).

    Note that 1-bit and 8-bit images are automatically converted to 32-bit
    integers if necessary to get a correct result.

.. py:function:: max(image1, image2)
    :noindex:

    Maximum value.

.. py:function:: min(image1, image2)
    :noindex:

    Minimum value.

---

### Reference ImageMorph (`docs/reference/ImageMorph.rst`)

.. py:module:: PIL.ImageMorph
.. py:currentmodule:: PIL.ImageMorph

:py:mod:`~PIL.ImageMorph` module
================================

The :py:mod:`~PIL.ImageMorph` module allows `morphology`_ operators ("MorphOp") to be
applied to 1 or L mode images::

  from PIL import Image, ImageMorph
  img = Image.open("Tests/images/hopper.bw")
  mop = ImageMorph.MorphOp(op_name="erosion4")
  count, imgOut = mop.apply(img)
  imgOut.show()

.. _morphology: https://en.wikipedia.org/wiki/Mathematical_morphology

In addition to applying operators, you can also analyse images.

You can inspect an image in isolation to determine which pixels are non-empty::

  print(mop.get_on_pixels(img))  # [(0, 0), (1, 0), (2, 0), ...]

Or you can retrieve a list of pixels that match the operator. This is the number of
pixels that will be non-empty after the operator is applied::

  coords = mop.match(img)
  print(coords)  # [(17, 1), (18, 1), (34, 1), ...]
  print(len(coords))  # 550

  imgOut = mop.apply(img)[1]
  print(len(mop.get_on_pixels(imgOut)))  # 550

If you would like more customized operators, you can pass patterns to the MorphOp
class::

  mop = ImageMorph.MorphOp(patterns=["1:(... ... ...)->0", "4:(00. 01. ...)->1"])

Or you can pass lookup table ("LUT") data directly. This LUT data can be constructed
with the :py:class:`~PIL.ImageMorph.LutBuilder`::

  builder = ImageMorph.LutBuilder()
  mop = ImageMorph.MorphOp(lut=builder.build_lut())

.. autoclass:: LutBuilder
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: MorphOp
    :members:
    :undoc-members:
    :show-inheritance:

---

### Reference ImageOps (`docs/reference/ImageOps.rst`)

.. py:module:: PIL.ImageOps
.. py:currentmodule:: PIL.ImageOps

:py:mod:`~PIL.ImageOps` module
==============================

The :py:mod:`~PIL.ImageOps` module contains a number of ‘ready-made’ image
processing operations. This module is somewhat experimental, and most operators
only work on L and RGB images.

.. versionadded:: 1.1.3

.. autofunction:: autocontrast
.. autofunction:: colorize
.. autofunction:: crop
.. autofunction:: scale
.. autoclass:: SupportsGetMesh
    :show-inheritance:
.. autofunction:: deform
.. autofunction:: equalize
.. autofunction:: expand
.. autofunction:: flip
.. autofunction:: grayscale
.. autofunction:: invert
.. autofunction:: mirror
.. autofunction:: posterize
.. autofunction:: solarize
.. autofunction:: exif_transpose

.. _relative-resize:

Resize relative to a given size
-------------------------------

::

    from PIL import Image, ImageOps
    size = (100, 150)
    with Image.open("Tests/images/hopper.webp") as im:
        ImageOps.contain(im, size).save("imageops_contain.webp")
        ImageOps.cover(im, size).save("imageops_cover.webp")
        ImageOps.fit(im, size).save("imageops_fit.webp")
        ImageOps.pad(im, size, color="#f00").save("imageops_pad.webp")

        # thumbnail() can also be used,
        # but will modify the image object in place
        im.thumbnail(size)
        im.save("image_thumbnail.webp")

+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|                | :py:meth:`~PIL.Image.Image.thumbnail`      | :py:meth:`~PIL.ImageOps.contain`            | :py:meth:`~PIL.ImageOps.cover`            | :py:meth:`~PIL.ImageOps.fit`            | :py:meth:`~PIL.ImageOps.pad`            |
+================+============================================+=============================================+===========================================+=========================================+=========================================+
|Given size      | ``(100, 150)``                             | ``(100, 150)``                              | ``(100, 150)``                            | ``(100, 150)``                          | ``(100, 150)``                          |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|Resulting image | .. image:: ../example/image_thumbnail.webp | .. image:: ../example/imageops_contain.webp | .. image:: ../example/imageops_cover.webp | .. image:: ../example/imageops_fit.webp | .. image:: ../example/imageops_pad.webp |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+
|Resulting size  | ``100×100``                                | ``100×100``                                 | ``150×150``                               | ``100×150``                             | ``100×150``                             |
+----------------+--------------------------------------------+---------------------------------------------+-------------------------------------------+-----------------------------------------+-----------------------------------------+

.. autofunction:: contain
.. autofunction:: cover
.. autofunction:: fit
.. autofunction:: pad

---

### Reference ImagePalette (`docs/reference/ImagePalette.rst`)

.. py:module:: PIL.ImagePalette
.. py:currentmodule:: PIL.ImagePalette

:py:mod:`~PIL.ImagePalette` module
==================================

The :py:mod:`~PIL.ImagePalette` module contains a class of the same name to
represent the color palette of palette mapped images.

.. note::

    The :py:class:`~PIL.ImagePalette.ImagePalette` class has several methods,
    but they are all marked as "experimental." Read that as you will. The
    ``[source]`` link is there for a reason.

.. autoclass:: PIL.ImagePalette.ImagePalette
    :members:

---

### Reference ImagePath (`docs/reference/ImagePath.rst`)

.. py:module:: PIL.ImagePath
.. py:currentmodule:: PIL.ImagePath

:py:mod:`~PIL.ImagePath` module
===============================

The :py:mod:`~PIL.ImagePath` module is used to store and manipulate 2-dimensional
vector data. Path objects can be passed to the methods on the
:py:mod:`~PIL.ImageDraw` module.

.. py:class:: Path

    A path object. The coordinate list can be any sequence object containing
    either 2-tuples [(x, y), …] or numeric values [x, y, …].

    You can also create a path object from another path object.

    In 1.1.6 and later, you can also pass in any object that implements
    Python’s buffer API. The buffer should provide read access, and contain C
    floats in machine byte order.

    The path object implements most parts of the Python sequence interface, and
    behaves like a list of (x, y) pairs. You can use len(), item access, and
    slicing as usual. However, this does not support slice assignment, or item
    and slice deletion.

    :param xy: A sequence. The sequence can contain 2-tuples [(x, y), ...]
               or a flat list of numbers [x, y, ...].

.. py:method:: Path.compact(distance=2)

    Compacts the path, by removing points that are close to each other. This
    method modifies the path in place, and returns the number of points left in
    the path.

    ``distance`` is measured as `Manhattan distance`_ and defaults to two
    pixels.

.. _Manhattan distance: https://en.wikipedia.org/wiki/Manhattan_distance

.. py:method:: Path.getbbox()

    Gets the bounding box of the path.

    :return: ``(x0, y0, x1, y1)``

.. py:method:: Path.map(function)

    Maps the path through a function.

.. py:method:: Path.tolist(flat=False)

    Converts the path to a Python list [(x, y), …].

    :param flat: By default, this function returns a list of 2-tuples
                 [(x, y), ...].  If this argument is ``True``, it
                 returns a flat list [x, y, ...] instead.
    :return: A list of coordinates. See ``flat``.

.. py:method:: Path.transform(matrix)

    Transforms the path in place, using an affine transform. The matrix is a
    6-tuple (a, b, c, d, e, f), and each point is mapped as follows::

        xOut = xIn * a + yIn * b + c
        yOut = xIn * d + yIn * e + f

---

### Reference ImageQt (`docs/reference/ImageQt.rst`)

.. py:module:: PIL.ImageQt
.. py:currentmodule:: PIL.ImageQt

:py:mod:`~PIL.ImageQt` module
=============================

The :py:mod:`~PIL.ImageQt` module contains support for creating PyQt6 or PySide6
QImage objects from PIL images.

.. versionadded:: 1.1.6

.. py:class:: ImageQt(image)

    Creates an :py:class:`~PIL.ImageQt.ImageQt` object from a PIL
    :py:class:`~PIL.Image.Image` object. This class is a subclass of
    QtGui.QImage, which means that you can pass the resulting objects directly
    to PyQt6/PySide6 API functions and methods.

    This operation is currently supported for mode 1, L, P, RGB, and RGBA
    images. To handle other modes, you need to convert the image first.

---

### Reference ImageSequence (`docs/reference/ImageSequence.rst`)

.. py:module:: PIL.ImageSequence
.. py:currentmodule:: PIL.ImageSequence

:py:mod:`~PIL.ImageSequence` module
===================================

The :py:mod:`~PIL.ImageSequence` module contains a wrapper class that lets you
iterate over the frames of an image sequence.

Extracting frames from an animation
-----------------------------------

::

    from PIL import Image, ImageSequence

    with Image.open("animation.fli") as im:
        index = 1
        for frame in ImageSequence.Iterator(im):
            frame.save(f"frame{index}.png")
            index += 1

The :py:class:`~PIL.ImageSequence.Iterator` class
-------------------------------------------------

.. autoclass:: PIL.ImageSequence.Iterator
    :members:

Functions
---------

.. autofunction:: PIL.ImageSequence.all_frames

---

### Reference ImageShow (`docs/reference/ImageShow.rst`)

.. py:module:: PIL.ImageShow
.. py:currentmodule:: PIL.ImageShow

:py:mod:`~PIL.ImageShow` module
===============================

The :py:mod:`~PIL.ImageShow` module is used to display images.
All default viewers convert the image to be shown to PNG format.

.. autofunction:: PIL.ImageShow.show

.. autoclass:: IPythonViewer
.. autoclass:: WindowsViewer
.. autoclass:: MacViewer

.. class:: UnixViewer

    The following viewers may be registered on Unix-based systems, if the given command is found:

    .. autoclass:: PIL.ImageShow.XDGViewer
    .. autoclass:: PIL.ImageShow.DisplayViewer
    .. autoclass:: PIL.ImageShow.GmDisplayViewer
    .. autoclass:: PIL.ImageShow.EogViewer
    .. autoclass:: PIL.ImageShow.XVViewer

    To provide maximum functionality on Unix-based systems, temporary files created
    from images will not be automatically removed by Pillow.

.. autofunction:: PIL.ImageShow.register
.. autoclass:: PIL.ImageShow.Viewer
    :member-order: bysource
    :members:
    :undoc-members:

---

### Reference ImageStat (`docs/reference/ImageStat.rst`)

.. py:module:: PIL.ImageStat
.. py:currentmodule:: PIL.ImageStat

:py:mod:`~PIL.ImageStat` module
===============================

The :py:mod:`~PIL.ImageStat` module calculates global statistics for an image, or
for a region of an image.

.. autoclass:: Stat
    :members:
    :special-members: __init__

---

### Reference ImageText (`docs/reference/ImageText.rst`)

.. py:module:: PIL.ImageText
.. py:currentmodule:: PIL.ImageText

:py:mod:`~PIL.ImageText` module
===============================

The :py:mod:`~PIL.ImageText` module defines a :py:class:`~PIL.ImageText.Text` class.
Instances of this class provide a way to use fonts with text strings or bytes. The
result is a simple API to apply styling to pieces of text and measure or draw them.

Example
-------

::

    from PIL import Image, ImageDraw, ImageFont, ImageText
    font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 24)

    text = ImageText.Text("Hello world", font)
    text.embed_color()
    text.stroke(2, "#0f0")

    print(text.get_length())  # 154.0
    print(text.get_bbox())  # (-2, 3, 156, 22)

    im = Image.new("RGB", text.get_bbox()[2:])
    d = ImageDraw.Draw(im)
    d.text((0, 0), text, "#f00")

Comparison
----------

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)

Methods
-------

.. autoclass:: PIL.ImageText.Text
    :members:

---

### Reference ImageTk (`docs/reference/ImageTk.rst`)

.. py:module:: PIL.ImageTk
.. py:currentmodule:: PIL.ImageTk

:py:mod:`~PIL.ImageTk` module
=============================

The :py:mod:`~PIL.ImageTk` module contains support to create and modify Tkinter
BitmapImage and PhotoImage objects from PIL images.

For examples, see the demo programs in the Scripts directory.

.. autoclass:: PIL.ImageTk.BitmapImage
    :members:

.. autoclass:: PIL.ImageTk.PhotoImage
    :members:

---

### Reference ImageTransform (`docs/reference/ImageTransform.rst`)

.. py:module:: PIL.ImageTransform
.. py:currentmodule:: PIL.ImageTransform

:py:mod:`~PIL.ImageTransform` module
====================================

The :py:mod:`~PIL.ImageTransform` module contains implementations of
:py:class:`~PIL.Image.ImageTransformHandler` for some of the builtin
:py:class:`.Image.Transform` methods.

.. autoclass:: Transform
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: AffineTransform
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: PerspectiveTransform
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: ExtentTransform
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: QuadTransform
    :members:
    :undoc-members:
    :show-inheritance:

.. autoclass:: MeshTransform
    :members:
    :undoc-members:
    :show-inheritance:

---

### Reference ImageWin (`docs/reference/ImageWin.rst`)

.. py:module:: PIL.ImageWin
.. py:currentmodule:: PIL.ImageWin

:py:mod:`~PIL.ImageWin` module (Windows-only)
=============================================

The :py:mod:`~PIL.ImageWin` module contains support to create and display images on
Windows.

ImageWin can be used with PythonWin and other user interface toolkits that
provide access to Windows device contexts or window handles. For example,
Tkinter makes the window handle available via the winfo_id method::

    from PIL import ImageWin

    dib = ImageWin.Dib(...)

    hwnd = ImageWin.HWND(widget.winfo_id())
    dib.draw(hwnd, xy)


.. autoclass:: PIL.ImageWin.Dib
    :members:

.. autoclass:: PIL.ImageWin.HDC
    :members:

.. autoclass:: PIL.ImageWin.HWND
    :members:

---

### Reference JpegPresets (`docs/reference/JpegPresets.rst`)

.. py:currentmodule:: PIL.JpegPresets

:py:mod:`~PIL.JpegPresets` module
=================================

.. automodule:: PIL.JpegPresets

    .. data:: presets
        :type: dict

        A dictionary of all supported presets.

---

### Reference PSDraw (`docs/reference/PSDraw.rst`)

.. py:module:: PIL.PSDraw
.. py:currentmodule:: PIL.PSDraw

:py:mod:`~PIL.PSDraw` module
============================

The :py:mod:`~PIL.PSDraw` module provides simple print support for PostScript
printers. You can print text, graphics and images through this module.

.. autoclass:: PIL.PSDraw.PSDraw
    :members:

---

### Reference PixelAccess (`docs/reference/PixelAccess.rst`)

.. _PixelAccess:

:py:class:`PixelAccess` class
=============================

The PixelAccess class provides read and write access to
:py:class:`PIL.Image` data at a pixel level.

.. note:: Accessing individual pixels is fairly slow. If you are
          looping over all of the pixels in an image, there is likely
          a faster way using other parts of the Pillow API.

          :mod:`~PIL.Image`, :mod:`~PIL.ImageChops` and :mod:`~PIL.ImageOps`
          have methods for many standard operations. If you wish to perform
          a custom mapping, check out :py:meth:`~PIL.Image.Image.point`.

Example
-------

The following script loads an image, accesses one pixel from it, then
changes it. ::

    from PIL import Image

    with Image.open("hopper.jpg") as im:
        px = im.load()
    print(px[4, 4])
    px[4, 4] = (0, 0, 0)
    print(px[4, 4])

Results in the following::

    (23, 24, 68)
    (0, 0, 0)

Access using negative indexes is also possible. ::

    px[-1, -1] = (0, 0, 0)
    print(px[-1, -1])



:py:class:`PixelAccess` class
-----------------------------

.. class:: PixelAccess
  :canonical: PIL.Image.core.PixelAccess

  .. method:: __getitem__(self, xy: tuple[int, int]) -> float | tuple[int, ...]

        Returns the pixel at x,y. The pixel is returned as a single
        value for single band images or a tuple for multi-band images.

        :param xy: The pixel coordinate, given as (x, y).
        :returns: a pixel value for single band images, a tuple of
                  pixel values for multiband images.

  .. method:: __setitem__(self, xy: tuple[int, int], color: float | tuple[int, ...]) -> None

        Modifies the pixel at x,y. The color is given as a single
        numerical value for single band images, and a tuple for
        multi-band images. See :ref:`colors` for more information.

        :param xy: The pixel coordinate, given as (x, y).
        :param color: The pixel value according to its mode,
                      e.g. tuple (r, g, b) for RGB mode.

---

### Reference TiffTags (`docs/reference/TiffTags.rst`)

.. py:module:: PIL.TiffTags
.. py:currentmodule:: PIL.TiffTags

:py:mod:`~PIL.TiffTags` module
==============================

The :py:mod:`~PIL.TiffTags` module exposes many of the standard TIFF
metadata tag numbers, names, and type information.

.. method:: lookup(tag)

    :param tag: Integer tag number
    :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in

    .. versionadded:: 8.3.0

    :returns: Taginfo namedtuple, from the :py:data:`~PIL.TiffTags.TAGS_V2` info if possible,
        otherwise just populating the value and name from :py:data:`~PIL.TiffTags.TAGS`.
        If the tag is not recognized, "unknown" is returned for the name

.. versionadded:: 3.1.0

.. class:: TagInfo

  .. method:: __init__(self, value=None, name="unknown", type=None, length=0, enum=None)

     :param value: Integer Tag Number
     :param name: Tag Name
     :param type: Integer type from :py:data:`PIL.TiffTags.TYPES`
     :param length: Array length: 0 == variable, 1 == single value, n = fixed
     :param enum: Dict of name:integer value options for an enumeration

  .. method:: cvt_enum(self, value)

     :param value: The enumerated value name
     :returns: The integer corresponding to the name.

.. versionadded:: 3.0.0

.. py:data:: PIL.TiffTags.TAGS_V2
    :type: dict

    The ``TAGS_V2`` dictionary maps 16-bit integer tag numbers to
    :py:class:`PIL.TiffTags.TagInfo` tuples for metadata fields defined in the TIFF
    spec.

.. versionadded:: 3.0.0

.. py:data:: PIL.TiffTags.TAGS_V2_GROUPS
    :type: dict

    :py:data:`~PIL.TiffTags.TAGS_V2` is one dimensional and
    doesn't account for the fact that tags actually exist in
    `different groups <https://exiftool.org/TagNames/EXIF.html>`_.
    This dictionary is used when the tag in question is part of a group.

.. versionadded:: 8.3.0

.. py:data:: PIL.TiffTags.TAGS
    :type: dict

    The ``TAGS`` dictionary maps 16-bit integer TIFF tag numbers to
    descriptive string names.  For instance:

        >>> from PIL.TiffTags import TAGS
        >>> TAGS[0x010e]
        'ImageDescription'

    This dictionary contains a superset of the tags in :py:data:`~PIL.TiffTags.TAGS_V2`, common
    EXIF tags, and other well-known metadata tags.

.. py:data:: PIL.TiffTags.TYPES
    :type: dict

    The ``TYPES`` dictionary maps the TIFF type short integer to a
    human readable type name.

.. py:data:: PIL.TiffTags.LIBTIFF_CORE
    :type: list

    A list of supported tag IDs when writing using LibTIFF.

---

### Reference Arrow Support (`docs/reference/arrow_support.rst`)

.. _arrow-support:

=============
Arrow support
=============

`Arrow <https://arrow.apache.org/>`__
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.

The goal with Arrow is to provide native zero-copy interoperability
with any Arrow provider or consumer in the Python ecosystem.

.. warning:: Zero-copy does not mean zero allocation -- the internal
  memory layout of Pillow images contains an allocation for row
  pointers, so there is a non-zero, but significantly smaller than a
  full-copy memory cost to reading an Arrow image.


Data formats
============

Pillow currently supports exporting Arrow images in all modes.

For single-band images, the exported array is width*height elements,
with each pixel corresponding to the appropriate Arrow type.

For multiband images, the exported array is width*height fixed-length
four-element arrays of uint8. This is memory compatible with the raw
image storage of four bytes per pixel.

Mode ``1`` images are exported as one uint8 byte/pixel, as this is
consistent with the internal storage.

Pillow will accept, but not produce, one other format. For any
multichannel image with 32-bit storage per pixel, Pillow will accept
an array of width*height int32 elements, which will then be
interpreted using the mode-specific interpretation of the bytes.

The image mode must match the Arrow band format when reading single
channel images.

Memory allocator
================

Pillow's default memory allocator, the :ref:`block_allocator`,
allocates up to a 16 MB block for images by default. Larger images
overflow into additional blocks. Arrow requires a single continuous
memory allocation, so images allocated in multiple blocks cannot be
exported in the Arrow format.

To enable the single block allocator::

  from PIL import Image
  Image.core.set_use_block_allocator(1)

Note that this is a global setting, not a per-image setting.

The rows of the image must also be contiguous. Images are not
exportable if the default allocator pads their rows to an alignment
(``PILLOW_ALIGNMENT``), or if they were created by
:py:func:`~PIL.Image.frombuffer` with a row stride or with bottom-up
rows.

Unsupported features
====================

* Table/dataframe protocol. We support a single array.
* Null markers, producing or consuming. Null values are inferred from
  the mode, e.g. RGB images are stored in the first three bytes of
  each 32-bit pixel, and the last byte is an implied null.
* Schema negotiation. There is an optional schema for the requested
  datatype in the Arrow source interface. We ignore that
  parameter.
* Array metadata.

Internal details
================

Python Arrow C interface:
https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html

The memory that is exported from the Arrow interface is shared -- not
copied, so the lifetime of the memory allocation is no longer strictly
tied to the life of the Python object.

The core imaging struct now has a refcount associated with it, and the
lifetime of the core image struct is now divorced from the Python
image object. Creating an arrow reference to the image increments the
refcount, and the imaging struct is only released when the refcount
reaches zero.

---

### Reference Block Allocator (`docs/reference/block_allocator.rst`)

.. _block_allocator:

Block allocator
===============

Previous design
---------------

Historically there have been two image allocators in Pillow:
``ImagingAllocateBlock`` and ``ImagingAllocateArray``. The first works
for images smaller than 16MB of data and allocates one large chunk of
memory of ``im->linesize * im->ysize`` bytes. The second works for
large images and makes one allocation for each scan line of size
``im->linesize`` bytes.  This makes for a very sharp transition
between one allocation and potentially thousands of small allocations,
leading to unpredictable performance penalties around the transition.

New design
----------

``ImagingAllocateArray`` now allocates space for images as a chain of
blocks with a maximum size of 16MB. If there is a memory allocation
error, it falls back to allocating a 4KB block, or at least one scan
line. This is now the default for all internal allocations.

``ImagingAllocateBlock`` is now only used for those cases when we are
specifically requesting a single segment of memory for sharing with
other code.

Memory pools
------------

There is now a memory pool to contain a supply of recently freed
blocks, which can then be reused without going back to the OS for a
fresh allocation. This caching of free blocks is currently disabled by
default, but can be enabled and tweaked using three environment
variables:

* ``PILLOW_ALIGNMENT``, in bytes. Specifies the alignment of memory
  allocations. Valid values are powers of 2 between 1 and
  128, inclusive. Defaults to 1.

* ``PILLOW_BLOCK_SIZE``, in bytes, K, or M.  Specifies the maximum
  block size for ``ImagingAllocateArray``. Valid values are
  integers, with an optional ``k`` or ``m`` suffix. Defaults to 16M.

* ``PILLOW_BLOCKS_MAX`` Specifies the number of freed blocks to
  retain to fill future memory requests. Any freed blocks over this
  threshold will be returned to the OS immediately. Defaults to 0.

---

### Reference C Extension Debugging (`docs/reference/c_extension_debugging.rst`)

C extension debugging on Linux, with GDB/Valgrind
=================================================

Install the tools
-----------------

You need some basics in addition to the basic tools to build
pillow. These are what's required on Ubuntu, YMMV for other
distributions.

-  ``python3-dbg`` package for the gdb extensions and python symbols
-  ``gdb`` and ``valgrind``
-  Potentially debug symbols for libraries. On Ubuntu you can follow those
   instructions to install the corresponding packages: `Debug Symbol Packages <https://ubuntu.com/server/docs/how-to/debugging/debug-symbol-packages/#getting-dbgsym-ddeb-packages>`_

Then ``sudo apt-get install libtiff5-dbgsym``

-  There's a bug with the ``python3-dbg`` package for at least Python 3.8 on
   Ubuntu 20.04, and you need to add a new link or two to make it autoload when
   running Python:

::

    cd /usr/share/gdb/auto-load/usr/bin
    ln -s python3.8m-gdb.py python3.8d-gdb.py

-  In Ubuntu 18.04, it's actually including the path to the virtualenv
   in the search for the ``python3.*-gdb.py`` file, but you can
   helpfully put in the same directory as the binary.

-  I also find that history is really useful for gdb, so I added this to
   my ``~/.gdbinit`` file:

::

    set history filename ~/.gdb_history
    set history save on

-  If the python stack isn't working in gdb, then
   ``set debug auto-load`` can also be helpful in ``.gdbinit``.

-  Make a virtualenv with the debug python and activate it, then install
   whatever dependencies are required and build. You want to build with
   the debug python so you get symbols for your extension.

::

    virtualenv -p python3.8-dbg ~/vpy38-dbg
    source ~/vpy38-dbg/bin/activate
    cd ~/Pillow && make install

Test case
---------

Take your test image, and make a really simple harness.

::

    from PIL import Image

    with Image.open(path) as im:
        im.load()

-  Run this through valgrind, but note that python triggers some issues
   on its own, so you're looking for items within the Pillow hierarchy
   that don't look like they're solely in the python call chain. In this
   example, the ones we're interested in are after the warnings, and have
   ``decode.c`` and ``TiffDecode.c`` in the call stack:

::

    (vpy38-dbg) ubuntu@primary:~/Home/tests$ valgrind python test_tiff.py
    ==51890== Memcheck, a memory error detector
    ==51890== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==51890== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
    ==51890== Command: python test_tiff.py
    ==51890==
    ==51890== Invalid read of size 4
    ==51890==    at 0x472E3D: address_in_range (obmalloc.c:1401)
    ==51890==    by 0x472EEA: pymalloc_free (obmalloc.c:1677)
    ==51890==    by 0x474960: _PyObject_Free (obmalloc.c:1896)
    ==51890==    by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
    ==51890==    by 0x473BD4: _PyMem_DebugFree (obmalloc.c:2318)
    ==51890==    by 0x474C08: PyObject_Free (obmalloc.c:709)
    ==51890==    by 0x45DD60: dictresize (dictobject.c:1259)
    ==51890==    by 0x45DD76: insertion_resize (dictobject.c:1019)
    ==51890==    by 0x464F30: PyDict_SetDefault (dictobject.c:2924)
    ==51890==    by 0x4D03BE: PyUnicode_InternInPlace (unicodeobject.c:15289)
    ==51890==    by 0x4D0700: PyUnicode_InternFromString (unicodeobject.c:15322)
    ==51890==    by 0x64D2FC: descr_new (descrobject.c:857)
    ==51890==  Address 0x4c1b020 is 384 bytes inside a block of size 1,160 free'd
    ==51890==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==51890==    by 0x4735D3: _PyMem_RawFree (obmalloc.c:127)
    ==51890==    by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
    ==51890==    by 0x474941: PyMem_RawFree (obmalloc.c:595)
    ==51890==    by 0x47496E: _PyObject_Free (obmalloc.c:1898)
    ==51890==    by 0x473BAC: _PyMem_DebugRawFree (obmalloc.c:2187)
    ==51890==    by 0x473BD4: _PyMem_DebugFree (obmalloc.c:2318)
    ==51890==    by 0x474C08: PyObject_Free (obmalloc.c:709)
    ==51890==    by 0x45DD60: dictresize (dictobject.c:1259)
    ==51890==    by 0x45DD76: insertion_resize (dictobject.c:1019)
    ==51890==    by 0x464F30: PyDict_SetDefault (dictobject.c:2924)
    ==51890==    by 0x4D03BE: PyUnicode_InternInPlace (unicodeobject.c:15289)
    ==51890==  Block was alloc'd at
    ==51890==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==51890==    by 0x473646: _PyMem_RawMalloc (obmalloc.c:99)
    ==51890==    by 0x473529: _PyMem_DebugRawAlloc (obmalloc.c:2120)
    ==51890==    by 0x473565: _PyMem_DebugRawMalloc (obmalloc.c:2153)
    ==51890==    by 0x4748B1: PyMem_RawMalloc (obmalloc.c:572)
    ==51890==    by 0x475909: _PyObject_Malloc (obmalloc.c:1628)
    ==51890==    by 0x473529: _PyMem_DebugRawAlloc (obmalloc.c:2120)
    ==51890==    by 0x473565: _PyMem_DebugRawMalloc (obmalloc.c:2153)
    ==51890==    by 0x4736B0: _PyMem_DebugMalloc (obmalloc.c:2303)
    ==51890==    by 0x474B78: PyObject_Malloc (obmalloc.c:685)
    ==51890==    by 0x45C435: new_keys_object (dictobject.c:558)
    ==51890==    by 0x45DA95: dictresize (dictobject.c:1202)
    ==51890==
    ==51890== Invalid read of size 4
    ==51890==    at 0x472E3D: address_in_range (obmalloc.c:1401)
    ==51890==    by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
    ==51890==    by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
    ==51890==    by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
    ==51890==    by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
    ==51890==    by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
    ==51890==    by 0x44A6FC: list_resize (listobject.c:70)
    ==51890==    by 0x44A872: app1 (listobject.c:340)
    ==51890==    by 0x44FD65: PyList_Append (listobject.c:352)
    ==51890==    by 0x514315: r_ref (marshal.c:945)
    ==51890==    by 0x516034: r_object (marshal.c:1139)
    ==51890==    by 0x516C70: r_object (marshal.c:1389)
    ==51890==  Address 0x4c41020 is 32 bytes before a block of size 1,600 in arena "client"
    ==51890==
    ==51890== Conditional jump or move depends on uninitialised value(s)
    ==51890==    at 0x472E46: address_in_range (obmalloc.c:1403)
    ==51890==    by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
    ==51890==    by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
    ==51890==    by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
    ==51890==    by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
    ==51890==    by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
    ==51890==    by 0x44A6FC: list_resize (listobject.c:70)
    ==51890==    by 0x44A872: app1 (listobject.c:340)
    ==51890==    by 0x44FD65: PyList_Append (listobject.c:352)
    ==51890==    by 0x5E3321: _posix_listdir (posixmodule.c:3823)
    ==51890==    by 0x5E33A8: os_listdir_impl (posixmodule.c:3879)
    ==51890==    by 0x5E4D77: os_listdir (posixmodule.c.h:1197)
    ==51890==
    ==51890== Use of uninitialised value of size 8
    ==51890==    at 0x472E59: address_in_range (obmalloc.c:1403)
    ==51890==    by 0x47594A: pymalloc_realloc (obmalloc.c:1929)
    ==51890==    by 0x475A02: _PyObject_Realloc (obmalloc.c:1982)
    ==51890==    by 0x473DCA: _PyMem_DebugRawRealloc (obmalloc.c:2240)
    ==51890==    by 0x473FF8: _PyMem_DebugRealloc (obmalloc.c:2326)
    ==51890==    by 0x4749FB: PyMem_Realloc (obmalloc.c:623)
    ==51890==    by 0x44A6FC: list_resize (listobject.c:70)
    ==51890==    by 0x44A872: app1 (listobject.c:340)
    ==51890==    by 0x44FD65: PyList_Append (listobject.c:352)
    ==51890==    by 0x5E3321: _posix_listdir (posixmodule.c:3823)
    ==51890==    by 0x5E33A8: os_listdir_impl (posixmodule.c:3879)
    ==51890==    by 0x5E4D77: os_listdir (posixmodule.c.h:1197)
    ==51890==
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 16908288 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67895296 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1572864 bytes but only got 0. Skipping tag 42
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 116647 bytes but only got 4867. Skipping tag 42738
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 3468830728 bytes but only got 4851. Skipping tag 279
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 2198732800 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67239937 bytes but only got 4125. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33947764 bytes but only got 0. Skipping tag 139
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 17170432 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 80478208 bytes but only got 0. Skipping tag 1
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 787460 bytes but only got 4882. Skipping tag 20
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1075 bytes but only got 0. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 120586240 bytes but only got 0. Skipping tag 194
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 65536 bytes but only got 0. Skipping tag 3
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 198656 bytes but only got 0. Skipping tag 279
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 206848 bytes but only got 0. Skipping tag 64512
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 130968 bytes but only got 4882. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 77848 bytes but only got 4689. Skipping tag 64270
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 262156 bytes but only got 0. Skipping tag 257
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33624064 bytes but only got 0. Skipping tag 49152
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67178752 bytes but only got 4627. Skipping tag 50688
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33632768 bytes but only got 0. Skipping tag 56320
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 134386688 bytes but only got 4115. Skipping tag 2048
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33912832 bytes but only got 0. Skipping tag 7168
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 151966208 bytes but only got 4627. Skipping tag 10240
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 119032832 bytes but only got 3859. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 46535680 bytes but only got 0. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 35651584 bytes but only got 0. Skipping tag 42
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 524288 bytes but only got 0. Skipping tag 0
      warnings.warn(
    _TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
    ZIPDecode: Decoding error at scanline 0, incorrect header check.
    ==51890== Invalid write of size 4
    ==51890==    at 0x61C39E6: putcontig8bitYCbCr22tile (tif_getimage.c:2146)
    ==51890==    by 0x61C5865: gtStripContig (tif_getimage.c:977)
    ==51890==    by 0x6094317: ReadStrip (TiffDecode.c:269)
    ==51890==    by 0x6094749: ImagingLibTiffDecode (TiffDecode.c:479)
    ==51890==    by 0x60615D1: _decode (decode.c:136)
    ==51890==    by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x43627B: function_code_fastcall (call.c:283)
    ==51890==    by 0x436D21: _PyFunction_Vectorcall (call.c:410)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==  Address 0x6f456d4 is 0 bytes after a block of size 68 alloc'd
    ==51890==    at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==51890==    by 0x60946D0: ImagingLibTiffDecode (TiffDecode.c:469)
    ==51890==    by 0x60615D1: _decode (decode.c:136)
    ==51890==    by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x43627B: function_code_fastcall (call.c:283)
    ==51890==    by 0x436D21: _PyFunction_Vectorcall (call.c:410)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x4DFDFB: _PyEval_EvalCodeWithName (ceval.c:4298)
    ==51890==    by 0x436C40: _PyFunction_Vectorcall (call.c:435)
    ==51890==
    ==51890== Invalid write of size 4
    ==51890==    at 0x61C39B5: putcontig8bitYCbCr22tile (tif_getimage.c:2145)
    ==51890==    by 0x61C5865: gtStripContig (tif_getimage.c:977)
    ==51890==    by 0x6094317: ReadStrip (TiffDecode.c:269)
    ==51890==    by 0x6094749: ImagingLibTiffDecode (TiffDecode.c:479)
    ==51890==    by 0x60615D1: _decode (decode.c:136)
    ==51890==    by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x43627B: function_code_fastcall (call.c:283)
    ==51890==    by 0x436D21: _PyFunction_Vectorcall (call.c:410)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==  Address 0x6f456d8 is 4 bytes after a block of size 68 alloc'd
    ==51890==    at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==51890==    by 0x60946D0: ImagingLibTiffDecode (TiffDecode.c:469)
    ==51890==    by 0x60615D1: _decode (decode.c:136)
    ==51890==    by 0x64BF47: method_vectorcall_VARARGS (descrobject.c:300)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x43627B: function_code_fastcall (call.c:283)
    ==51890==    by 0x436D21: _PyFunction_Vectorcall (call.c:410)
    ==51890==    by 0x4EB73C: _PyObject_Vectorcall (abstract.h:127)
    ==51890==    by 0x4EB73C: call_function (ceval.c:4963)
    ==51890==    by 0x4EB73C: _PyEval_EvalFrameDefault (ceval.c:3486)
    ==51890==    by 0x4DF2EE: PyEval_EvalFrameEx (ceval.c:741)
    ==51890==    by 0x4DFDFB: _PyEval_EvalCodeWithName (ceval.c:4298)
    ==51890==    by 0x436C40: _PyFunction_Vectorcall (call.c:435)
    ==51890==
    TIFFFillStrip: Invalid strip byte count 0, strip 1.
    Traceback (most recent call last):
      File "test_tiff.py", line 8, in <module>
        im.load()
      File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1087, in load
        return self._load_libtiff()
      File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1191, in _load_libtiff
        raise OSError(err)
    OSError: -2
    sys:1: ResourceWarning: unclosed file <_io.BufferedReader name='crash-2020-10-test.tiff'>
    ==51890==
    ==51890== HEAP SUMMARY:
    ==51890==     in use at exit: 748,734 bytes in 444 blocks
    ==51890==   total heap usage: 6,320 allocs, 5,876 frees, 69,142,969 bytes allocated
    ==51890==
    ==51890== LEAK SUMMARY:
    ==51890==    definitely lost: 0 bytes in 0 blocks
    ==51890==    indirectly lost: 0 bytes in 0 blocks
    ==51890==      possibly lost: 721,538 bytes in 372 blocks
    ==51890==    still reachable: 27,196 bytes in 72 blocks
    ==51890==         suppressed: 0 bytes in 0 blocks
    ==51890== Rerun with --leak-check=full to see details of leaked memory
    ==51890==
    ==51890== Use --track-origins=yes to see where uninitialised values come from
    ==51890== For lists of detected and suppressed errors, rerun with: -s
    ==51890== ERROR SUMMARY: 2556 errors from 6 contexts (suppressed: 0 from 0)
    (vpy38-dbg) ubuntu@primary:~/Home/tests$

-  Now that we've confirmed that there's something odd/bad going on,
   it's time to gdb.
-  Start with ``gdb python``
-  Set a break point starting with the valgrind stack trace.
   ``b TiffDecode.c:269``
-  Run the script with ``r test_tiff.py``
-  When the break point is hit, explore the state with ``info locals``,
   ``bt``, ``py-bt``, or ``p [variable]``. For pointers,
   ``p *[variable]`` is useful.

::

    (vpy38-dbg) ubuntu@primary:~/Home/tests$ gdb python
    GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
    Copyright (C) 2020 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <https://www.gnu.org/software/gdb/documentation/>.

    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from python...
    (gdb) b TiffDecode.c:269
    No source file named TiffDecode.c.
    Make breakpoint pending on future shared library load? (y or [n]) y
    Breakpoint 1 (TiffDecode.c:269) pending.
    (gdb) r test_tiff.py
    Starting program: /home/ubuntu/vpy38-dbg/bin/python test_tiff.py
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 16908288 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67895296 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1572864 bytes but only got 0. Skipping tag 42
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 116647 bytes but only got 4867. Skipping tag 42738
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 3468830728 bytes but only got 4851. Skipping tag 279
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 2198732800 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67239937 bytes but only got 4125. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33947764 bytes but only got 0. Skipping tag 139
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 17170432 bytes but only got 0. Skipping tag 0
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 80478208 bytes but only got 0. Skipping tag 1
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 787460 bytes but only got 4882. Skipping tag 20
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 1075 bytes but only got 0. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 120586240 bytes but only got 0. Skipping tag 194
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 65536 bytes but only got 0. Skipping tag 3
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 198656 bytes but only got 0. Skipping tag 279
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 206848 bytes but only got 0. Skipping tag 64512
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 130968 bytes but only got 4882. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 77848 bytes but only got 4689. Skipping tag 64270
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 262156 bytes but only got 0. Skipping tag 257
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33624064 bytes but only got 0. Skipping tag 49152
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 67178752 bytes but only got 4627. Skipping tag 50688
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33632768 bytes but only got 0. Skipping tag 56320
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 134386688 bytes but only got 4115. Skipping tag 2048
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 33912832 bytes but only got 0. Skipping tag 7168
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 151966208 bytes but only got 4627. Skipping tag 10240
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 119032832 bytes but only got 3859. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 46535680 bytes but only got 0. Skipping tag 256
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 35651584 bytes but only got 0. Skipping tag 42
      warnings.warn(
    /home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py:770: UserWarning: Possibly corrupt EXIF data.  Expecting to read 524288 bytes but only got 0. Skipping tag 0
      warnings.warn(
    _TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 769" (type 1, writecount -3, passcount 1).
    _TIFFVSetField: tempfile.tif: Null count for "Tag 42754" (type 1, writecount -3, passcount 1).

    Breakpoint 1, ReadStrip (tiff=tiff@entry=0xae9b90, row=0, buffer=0xac2eb0) at src/libImaging/TiffDecode.c:269
    269                 ok = TIFFRGBAImageGet(&img, buffer, img.width, rows_to_read);
    (gdb) p img
    $1 = {tif = 0xae9b90, stoponerr = 0, isContig = 1, alpha = 0, width = 20, height = 1536, bitspersample = 8, samplesperpixel = 3,
      orientation = 1, req_orientation = 1, photometric = 6, redcmap = 0x0, greencmap = 0x0, bluecmap = 0x0, get =
        0x7ffff71d0710 <gtStripContig>, put = {any = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>,
        contig = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>, separate = 0x7ffff71ce550 <putcontig8bitYCbCr22tile>}, Map = 0x0,
      BWmap = 0x0, PALmap = 0x0, ycbcr = 0xaf24b0, cielab = 0x0, UaToAa = 0x0, Bitdepth16To8 = 0x0, row_offset = 0, col_offset = 0}
    (gdb) up
    #1  0x00007ffff736174a in ImagingLibTiffDecode (im=0xac1f90, state=0x7ffff76767e0, buffer=<optimized out>, bytes=<optimized out>)
        at src/libImaging/TiffDecode.c:479
    479                 if (ReadStrip(tiff, state->y, (UINT32 *)state->buffer) == -1) {
    (gdb) p *state
    $2 = {count = 0, state = 0, errcode = 0, x = 0, y = 0, ystep = 0, xsize = 17, ysize = 108, xoff = 0, yoff = 0,
      shuffle = 0x7ffff735f411 <copy4>, bits = 32, bytes = 68, buffer = 0xac2eb0 "P\354\336\367\377\177", context = 0xa75440, fd = 0x0}
    (gdb) py-bt
    Traceback (most recent call first):
      File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1428, in _load_libtiff

      File "/home/ubuntu/vpy38-dbg/lib/python3.8/site-packages/Pillow-8.0.1-py3.8-linux-x86_64.egg/PIL/TiffImagePlugin.py", line 1087, in load
        return self._load_libtiff()
      File "test_tiff.py", line 8, in <module>
        im.load()

-  Poke around till you understand what's going on. In this case,
   state->xsize and img.width are different, which led to an out of
   bounds write, as the receiving buffer was sized for the smaller of
   the two.

Caveats
-------

-  If your program is running/hung in a docker container and your host
   has the appropriate tools, you can run gdb as the superuser in the
   host and you may be able to get a trace of where the process is hung.
   You probably won't have the capability to do that from within the
   docker container, as the trace capacity isn't allowed by default.

-  Variations of this are possible on macOS/Windows, but the details are
   going to be different.

-  IIRC, Fedora has the gdb bits working by default. Ubuntu has always
   been a bit of a battle to make it work.

---

### Reference Features (`docs/reference/features.rst`)

.. py:module:: PIL.features
.. py:currentmodule:: PIL.features

:py:mod:`~PIL.features` module
==============================

The :py:mod:`PIL.features` module can be used to detect which Pillow features are available on your system.

.. autofunction:: PIL.features.pilinfo
.. autofunction:: PIL.features.check
.. autofunction:: PIL.features.version
.. autofunction:: PIL.features.get_supported

Modules
-------

Support for the following modules can be checked:

* ``pil``: The Pillow core module, required for all functionality.
* ``tkinter``: Tkinter support.
* ``freetype2``: FreeType font support via :py:func:`PIL.ImageFont.truetype`.
* ``littlecms2``: LittleCMS 2 support via :py:mod:`PIL.ImageCms`.
* ``webp``: WebP image support.
* ``avif``: AVIF image support.

.. autofunction:: PIL.features.check_module
.. autofunction:: PIL.features.version_module
.. autofunction:: PIL.features.get_supported_modules

Codecs
------

Support for these is only checked during Pillow compilation.
If the required library was uninstalled from the system, the ``pil`` core module may fail to load instead.
Except for ``jpg``, the version number is checked at run-time.

Support for the following codecs can be checked:

* ``jpg``: (compile time) Libjpeg support, required for JPEG based image formats. Only compile time version number is available.
* ``jpg_2000``: (compile time) OpenJPEG support, required for JPEG 2000 image formats.
* ``zlib``: (compile time) Zlib support, required for zlib compressed formats, such as PNG.
* ``libtiff``: (compile time) LibTIFF support, required for TIFF based image formats.

.. autofunction:: PIL.features.check_codec
.. autofunction:: PIL.features.version_codec
.. autofunction:: PIL.features.get_supported_codecs

Features
--------

Some of these are only checked during Pillow compilation.
If the required library was uninstalled from the system, the relevant module may fail to load instead.
Feature version numbers are available only where stated.

Support for the following features can be checked:

* ``libjpeg_turbo``: (compile time) Whether Pillow was compiled against the libjpeg-turbo version of libjpeg. Compile-time version number is available.
* ``mozjpeg``: (compile time) Whether Pillow was compiled against the MozJPEG version of libjpeg. Compile-time version number is available.
* ``zlib_ng``: (compile time) Whether Pillow was compiled against the zlib-ng version of zlib. Compile-time version number is available.
* ``raqm``: Raqm library, required for ``ImageFont.Layout.RAQM`` in :py:func:`PIL.ImageFont.truetype`. Run-time version number is available for Raqm 0.7.0 or newer.
* ``libimagequant``: (compile time) ImageQuant quantization support in :py:func:`PIL.Image.Image.quantize`. Run-time version number is available.
* ``xcb``: (compile time) Support for X11 in :py:func:`PIL.ImageGrab.grab` via the XCB library.

.. autofunction:: PIL.features.check_feature
.. autofunction:: PIL.features.version_feature
.. autofunction:: PIL.features.get_supported_features

---

### Reference Index (`docs/reference/index.rst`)

Reference
=========

.. toctree::
   :maxdepth: 2


   Image
   ImageChops
   ImageCms
   ImageColor
   ImageDraw
   ImageEnhance
   ImageFile
   ImageFilter
   ImageFont
   ImageGrab
   ImageMath
   ImageMorph
   ImageOps
   ImagePalette
   ImagePath
   ImageQt
   ImageSequence
   ImageShow
   ImageStat
   ImageText
   ImageTk
   ImageTransform
   ImageWin
   ExifTags
   TiffTags
   JpegPresets
   PSDraw
   PixelAccess
   features
   ../PIL
   plugins
   internal_design

---

### Reference Internal Design (`docs/reference/internal_design.rst`)

Internal reference
==================

.. toctree::
  :maxdepth: 2

  open_files
  limits
  block_allocator
  internal_modules
  c_extension_debugging
  arrow_support

---

### Reference Internal Modules (`docs/reference/internal_modules.rst`)

Internal modules
================

:mod:`~PIL._binary` module
--------------------------

.. automodule:: PIL._binary
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL._deprecate` module
-----------------------------

.. automodule:: PIL._deprecate
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL._tkinter_finder` module
----------------------------------

.. automodule:: PIL._tkinter_finder
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL._typing` module
--------------------------

.. module:: PIL._typing

Provides a convenient way to import type hints that are not available
on some Python versions.

.. py:class:: Buffer

    Typing alias.

.. py:class:: Coords

    Typing alias.

.. py:class:: IntegralLike

    Typing alias.

.. py:class:: NumpyArray

    Typing alias.

.. py:class:: StrOrBytesPath

    Typing alias.

.. py:class:: SupportsRead

    An object that supports the read method.

:mod:`~PIL._util` module
------------------------

.. automodule:: PIL._util
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL._version` module
---------------------------

.. module:: PIL._version

.. data:: __version__
    :annotation:
    :type: str

    This is the master version number for Pillow,
    all other uses reference this module.

:mod:`PIL.Image.core` module
----------------------------

.. module:: PIL._imaging
.. module:: PIL.Image.core

An internal interface module previously known as :mod:`~PIL._imaging`,
implemented in :file:`_imaging.c`.

Pillow is a Python library, and the C interfaces within are for internal use only.
They may change without a deprecation period or a mention in the release notes.

.. py:class:: ImagingCore

    A representation of the image data.

---

### Reference Limits (`docs/reference/limits.rst`)

Limits
------

This page is documentation to the various fundamental size limits in
the Pillow implementation.

Internal limits
===============

* Image sizes cannot be negative. These are checked both in
  ``Storage.c`` and ``Image.py``

* Image sizes may be 0. (Although not in 3.4)

* Maximum pixel dimensions are limited to INT32, or 2^31 by the sizes
  in the image header.

* Individual allocations are limited to 2GB in ``Storage.c``

* The 2GB allocation puts an upper limit to the xsize of the image of
  either 2^31 for 'L' or 2^29 for 'RGB'

* Individual memory mapped segments are limited to 2GB in map.c based
  on the overflow checks. This requires that any memory mapped image
  is smaller than 2GB, as calculated by ``y*stride`` (so 2Gpx for 'L'
  images, and .5Gpx for 'RGB')

Format size limits
==================

* ICO: Max size is 256x256

* WebP: 16383x16383 (underlying library size limit:
  https://developers.google.com/speed/webp/docs/api)

---

### Reference Open Files (`docs/reference/open_files.rst`)

.. _file-handling:

File handling in Pillow
=======================

When opening a file as an image, Pillow requires a filename, ``os.PathLike``
object, or a file-like object. Pillow uses the filename or ``Path`` to open a
file, so for the rest of this article, they will all be treated as a file-like
object.

The following are all equivalent::

    from PIL import Image
    import io
    import pathlib

    with Image.open("test.jpg") as im:
        ...

    with Image.open(pathlib.Path("test.jpg")) as im2:
        ...

    with open("test.jpg", "rb") as f:
        im3 = Image.open(f)
        ...

    with open("test.jpg", "rb") as f:
        im4 = Image.open(io.BytesIO(f.read()))
        ...

If a filename or a path-like object is passed to Pillow, then the resulting
file object opened by Pillow may also be closed by Pillow after the
``Image.Image.load()`` method is called, provided the associated image does not
have multiple frames.

Pillow cannot in general close and reopen a file, so any access to
that file needs to be prior to the close.

Image lifecycle
---------------

* ``Image.open()`` Filenames and ``Path`` objects are opened as a file.
  Metadata is read from the open file. The file is left open for further usage.

* ``Image.Image.load()`` When the pixel data from the image is
  required, ``load()`` is called. The current frame is read into
  memory. The image can now be used independently of the underlying
  image file.

  Any Pillow method that creates a new image instance based on another will
  internally call ``load()`` on the original image and then read the data.
  The new image instance will not be associated with the original image file.

  If a filename or a ``Path`` object was passed to ``Image.open()``, then the
  file object was opened by Pillow and is considered to be used exclusively by
  Pillow. So if the image is a single-frame image, the file will be closed in
  this method after the frame is read. If the image is a multi-frame image,
  (e.g. multipage TIFF and animated GIF) the image file is left open so that
  ``Image.Image.seek()`` can load the appropriate frame.

* ``Image.Image.close()`` Closes the file and destroys the core image object.

  The Pillow context manager will also close the file, but will not destroy
  the core image object. e.g.::

    with Image.open("test.jpg") as img:
        img.load()
    assert img.fp is None
    img.save("test.png")


The lifecycle of a single-frame image is relatively simple. The file must
remain open until the ``load()`` or ``close()`` function is called or the
context manager exits.

Multi-frame images are more complicated. The ``load()`` method is not
a terminal method, so it should not close the underlying file. In general,
Pillow does not know if there are going to be any requests for additional
data until the caller has explicitly closed the image.


Complications
-------------

* ``TiffImagePlugin`` has some code to pass the underlying file descriptor into
  libtiff (if working on an actual file). Since libtiff closes the file
  descriptor internally, it is duplicated prior to passing it into libtiff.

* After a file has been closed, operations that require file access will fail::

    with open("test.jpg", "rb") as f:
        im5 = Image.open(f)
    im5.load()  # FAILS, closed file

    with Image.open("test.jpg") as im6:
        pass
    im6.load()  # FAILS, closed file


Proposed file handling
----------------------

* ``Image.Image.load()`` should close the image file, unless there are
  multiple frames.

* ``Image.Image.seek()`` should never close the image file.

* Users of the library should use a context manager or call
  ``Image.Image.close()`` on any image opened with a filename or ``Path``
  object to ensure that the underlying file is closed.

---

### Reference Plugins (`docs/reference/plugins.rst`)

Plugin reference
================

:mod:`~PIL.AvifImagePlugin` module
----------------------------------

.. automodule:: PIL.AvifImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.BmpImagePlugin` module
---------------------------------

.. automodule:: PIL.BmpImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.BufrStubImagePlugin` module
--------------------------------------

.. automodule:: PIL.BufrStubImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.CurImagePlugin` module
---------------------------------

.. automodule:: PIL.CurImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.DcxImagePlugin` module
---------------------------------

.. automodule:: PIL.DcxImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.DdsImagePlugin` module
---------------------------------

.. automodule:: PIL.DdsImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.EpsImagePlugin` module
---------------------------------

.. automodule:: PIL.EpsImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.FitsImagePlugin` module
----------------------------------

.. automodule:: PIL.FitsImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.FliImagePlugin` module
---------------------------------

.. automodule:: PIL.FliImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.FpxImagePlugin` module
---------------------------------

.. automodule:: PIL.FpxImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GbrImagePlugin` module
---------------------------------

.. automodule:: PIL.GbrImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GifImagePlugin` module
---------------------------------

.. automodule:: PIL.GifImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.GribStubImagePlugin` module
--------------------------------------

.. automodule:: PIL.GribStubImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.Hdf5StubImagePlugin` module
--------------------------------------

.. automodule:: PIL.Hdf5StubImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.IcnsImagePlugin` module
----------------------------------

.. automodule:: PIL.IcnsImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.IcoImagePlugin` module
---------------------------------

.. automodule:: PIL.IcoImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.ImImagePlugin` module
--------------------------------

.. automodule:: PIL.ImImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.ImtImagePlugin` module
---------------------------------

.. automodule:: PIL.ImtImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.IptcImagePlugin` module
----------------------------------

.. automodule:: PIL.IptcImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.JpegImagePlugin` module
----------------------------------

.. automodule:: PIL.JpegImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.Jpeg2KImagePlugin` module
------------------------------------

.. automodule:: PIL.Jpeg2KImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.McIdasImagePlugin` module
------------------------------------

.. automodule:: PIL.McIdasImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.MicImagePlugin` module
---------------------------------

.. automodule:: PIL.MicImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.MpegImagePlugin` module
----------------------------------

.. automodule:: PIL.MpegImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.MpoImagePlugin` module
---------------------------------

.. automodule:: PIL.MpoImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.MspImagePlugin` module
---------------------------------

.. automodule:: PIL.MspImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PalmImagePlugin` module
----------------------------------

.. automodule:: PIL.PalmImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PcdImagePlugin` module
---------------------------------

.. automodule:: PIL.PcdImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PcxImagePlugin` module
---------------------------------

.. automodule:: PIL.PcxImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PdfImagePlugin` module
---------------------------------

.. automodule:: PIL.PdfImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PixarImagePlugin` module
-----------------------------------

.. automodule:: PIL.PixarImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PngImagePlugin` module
---------------------------------

.. automodule:: PIL.PngImagePlugin
    :members: ChunkStream, PngImageFile, PngStream, getchunks, is_cid, putchunk,
        Blend, Disposal, MAX_TEXT_CHUNK, MAX_TEXT_MEMORY
    :undoc-members:
    :show-inheritance:
    :member-order: groupwise


:mod:`~PIL.PpmImagePlugin` module
---------------------------------

.. automodule:: PIL.PpmImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.PsdImagePlugin` module
---------------------------------

.. automodule:: PIL.PsdImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.SgiImagePlugin` module
---------------------------------

.. automodule:: PIL.SgiImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.SpiderImagePlugin` module
------------------------------------

.. automodule:: PIL.SpiderImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.SunImagePlugin` module
---------------------------------

.. automodule:: PIL.SunImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.TgaImagePlugin` module
---------------------------------

.. automodule:: PIL.TgaImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.TiffImagePlugin` module
----------------------------------

.. automodule:: PIL.TiffImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.WebPImagePlugin` module
----------------------------------

.. automodule:: PIL.WebPImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.WmfImagePlugin` module
---------------------------------

.. automodule:: PIL.WmfImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.XVThumbImagePlugin` module
-------------------------------------

.. automodule:: PIL.XVThumbImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.XbmImagePlugin` module
---------------------------------

.. automodule:: PIL.XbmImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

:mod:`~PIL.XpmImagePlugin` module
---------------------------------

.. automodule:: PIL.XpmImagePlugin
    :members:
    :undoc-members:
    :show-inheritance:

---

### Releasenotes 10.0.0 (`docs/releasenotes/10.0.0.rst`)

10.0.0
------

Security
========

Limit size even if one dimension is zero
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When performing decompression bomb checks, Pillow did not reject images with
excessive width and zero height, or zero width and excessive height. That has
now been fixed.

This effectively dates to the PIL fork, since problem images would still have
been processed before Pillow started checking for decompression bombs.

.. _Added ImageFont.MAX_STRING_LENGTH:

:cve:`2023-44271`: Added ImageFont.MAX_STRING_LENGTH
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To protect against potential DOS attacks when using arbitrary strings as text
input, Pillow will now raise a :py:exc:`ValueError` if the number of characters
passed into ImageFont methods is over a certain limit,
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.

This threshold can be changed by setting
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It can be disabled by setting
``ImageFont.MAX_STRING_LENGTH = None``.

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

Categories
^^^^^^^^^^

``im.category`` has been removed, along with the related ``Image.NORMAL``,
``Image.SEQUENCE`` and ``Image.CONTAINER`` attributes.

To determine if an image has multiple frames or not,
``getattr(im, "is_animated", False)`` can be used instead.

Tk/Tcl 8.4
^^^^^^^^^^

Support for Tk/Tcl 8.4 has been removed.

JpegImagePlugin.convert_dict_qtables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since deprecation in Pillow 8.3.0, the ``convert_dict_qtables`` method no longer
performed any operations on the data given to it, and has been removed.

ImagePalette size parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Before Pillow 8.3.0, ``ImagePalette`` required palette data of particular lengths by
default, and the ``size`` parameter could be used to override that. Pillow 8.3.0
removed the default required length, also removing the need for the ``size`` parameter.

ImageShow.Viewer.show_file file argument
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``file`` argument in :py:meth:`~PIL.ImageShow.Viewer.show_file()` has been
removed and replaced by ``path``.

In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.

Constants
^^^^^^^^^

A number of constants have been removed.
Instead, :py:class:`enum.IntEnum` classes have been added.

=====================================================  ============================================================
Removed                                                Use instead
=====================================================  ============================================================
``Image.LINEAR``                                       ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
``Image.CUBIC``                                        ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
``Image.ANTIALIAS``                                    ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
``ImageCms.INTENT_PERCEPTUAL``                         ``ImageCms.Intent.PERCEPTUAL``
``ImageCms.INTENT_RELATIVE_COLORMETRIC``               ``ImageCms.Intent.RELATIVE_COLORMETRIC``
``ImageCms.INTENT_SATURATION``                         ``ImageCms.Intent.SATURATION``
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC``              ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
``ImageCms.DIRECTION_INPUT``                           ``ImageCms.Direction.INPUT``
``ImageCms.DIRECTION_OUTPUT``                          ``ImageCms.Direction.OUTPUT``
``ImageCms.DIRECTION_PROOF``                           ``ImageCms.Direction.PROOF``
``ImageFont.LAYOUT_BASIC``                             ``ImageFont.Layout.BASIC``
``ImageFont.LAYOUT_RAQM``                              ``ImageFont.Layout.RAQM``
``BlpImagePlugin.BLP_FORMAT_JPEG``                     ``BlpImagePlugin.Format.JPEG``
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED``           ``BlpImagePlugin.Encoding.UNCOMPRESSED``
``BlpImagePlugin.BLP_ENCODING_DXT``                    ``BlpImagePlugin.Encoding.DXT``
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA``  ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1``             ``BlpImagePlugin.AlphaEncoding.DXT1``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3``             ``BlpImagePlugin.AlphaEncoding.DXT3``
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5``             ``BlpImagePlugin.AlphaEncoding.DXT5``
``FtexImagePlugin.FORMAT_DXT1``                        ``FtexImagePlugin.Format.DXT1``
``FtexImagePlugin.FORMAT_UNCOMPRESSED``                ``FtexImagePlugin.Format.UNCOMPRESSED``
``PngImagePlugin.APNG_DISPOSE_OP_NONE``                ``PngImagePlugin.Disposal.OP_NONE``
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND``          ``PngImagePlugin.Disposal.OP_BACKGROUND``
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS``            ``PngImagePlugin.Disposal.OP_PREVIOUS``
``PngImagePlugin.APNG_BLEND_OP_SOURCE``                ``PngImagePlugin.Blend.OP_SOURCE``
``PngImagePlugin.APNG_BLEND_OP_OVER``                  ``PngImagePlugin.Blend.OP_OVER``
=====================================================  ============================================================

FitsStubImagePlugin
^^^^^^^^^^^^^^^^^^^

The stub image plugin ``FitsStubImagePlugin`` has been removed.
FITS images can be read without a handler through :mod:`~PIL.FitsImagePlugin` instead.

Font size and offset methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Several functions for computing the size and offset of rendered text have been removed:

=============================================================== =============================================================================================================
Removed                                                         Use instead
=============================================================== =============================================================================================================
``FreeTypeFont.getsize()`` and ``FreeTypeFont.getoffset()``     :py:meth:`.FreeTypeFont.getbbox` and :py:meth:`.FreeTypeFont.getlength`
``FreeTypeFont.getsize_multiline()``                            :py:meth:`.ImageDraw.multiline_textbbox`
``ImageFont.getsize()``                                         :py:meth:`.ImageFont.getbbox` and :py:meth:`.ImageFont.getlength`
``TransposedFont.getsize()``                                    :py:meth:`.TransposedFont.getbbox` and :py:meth:`.TransposedFont.getlength`
``ImageDraw.textsize()`` and ``ImageDraw.multiline_textsize()`` :py:meth:`.ImageDraw.textbbox`, :py:meth:`.ImageDraw.textlength` and :py:meth:`.ImageDraw.multiline_textbbox`
``ImageDraw2.Draw.textsize()``                                  :py:meth:`.ImageDraw2.Draw.textbbox` and :py:meth:`.ImageDraw2.Draw.textlength`
=============================================================== =============================================================================================================

FreeTypeFont.getmask2 fill parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The undocumented ``fill`` parameter of :py:meth:`.FreeTypeFont.getmask2` has been
removed.

PhotoImage.paste box parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``box`` parameter was unused and has been removed.

PyQt5 and PySide2
^^^^^^^^^^^^^^^^^

`Qt 5 reached end-of-life <https://www.qt.io/blog/qt-5.15-released>`_ on 2020-12-08 for
open-source users (and will reach EOL on 2023-12-08 for commercial licence holders).

Support for PyQt5 and PySide2 has been removed from ``ImageQt``. Upgrade to
`PyQt6 <https://www.riverbankcomputing.com/static/Docs/PyQt6/>`_ or
`PySide6 <https://doc.qt.io/qtforpython-6/>`_ instead.

Image.coerce_e
^^^^^^^^^^^^^^

This undocumented method has been removed.

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

PyAccess and Image.USE_CFFI_ACCESS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Since Pillow's C API is now faster than PyAccess on PyPy,
:py:mod:`!PyAccess` has been deprecated and will be removed in Pillow
11.0.0 (2024-10-15). Pillow's C API will now be used by default on PyPy instead.

``Image.USE_CFFI_ACCESS``, for switching from the C API to PyAccess, is
similarly deprecated.

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

Added line width parameter to ImageDraw regular_polygon
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An optional line ``width`` parameter has been added to
``ImageDraw.Draw.regular_polygon``.

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

Added ``alpha_only`` argument to ``getbbox()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.Image.getbbox` now accepts a keyword argument of
``alpha_only``. This is an optional flag, defaulting to ``True``. If ``True``
and the image has an alpha channel, trim transparent pixels. Otherwise, trim
pixels when all channels are zero.

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

32-bit wheels
^^^^^^^^^^^^^

32-bit wheels are no longer provided.

Support display_jpeg() in IPython
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In addition to ``display()`` and ``display_png``, ``display_jpeg()`` can now
also be used to display images in IPython::

    from PIL import Image
    from IPython.display import display_jpeg

    im = Image.new("RGB", (100, 100), (255, 0, 0))
    display_jpeg(im)

Support reading signed 8-bit TIFF images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TIFF images with signed integer data, 8 bits per sample and a photometric
interpretation of BlackIsZero can now be read.

---

### Releasenotes 10.0.1 (`docs/releasenotes/10.0.1.rst`)

10.0.1
------

Security
========

:cve:`2023-4863`: Updated install script and updated wheels
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This release provides an updated install script and updated wheels to
include libwebp 1.3.2, preventing a potential heap buffer overflow in
WebP.

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

Updated tests to pass with latest zlib version
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The release of zlib 1.3 caused one of the tests in the Pillow test suite to fail.

---

### Releasenotes 10.1.0 (`docs/releasenotes/10.1.0.rst`)

10.1.0
------

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

Setting image mode
^^^^^^^^^^^^^^^^^^

If you attempt to set the mode of an image directly, e.g.
``im.mode = "RGBA"``, you will now receive an :py:exc:`AttributeError`. This is
not about removing existing functionality, but instead about raising an
explicit error to prevent later consequences. The ``convert`` method is the
correct way to change an image's mode.

Accept a list in getpixel()
^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.Image.getpixel` now accepts a list of coordinates, as well
as a tuple. ::

    from PIL import Image
    im = Image.new("RGB", (1, 1))
    im.getpixel((0, 0))
    im.getpixel([0, 0])

BoxBlur and GaussianBlur allow for different x and y radii
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.ImageFilter.BoxBlur` and
:py:class:`~PIL.ImageFilter.GaussianBlur` now allow a sequence of x and y radii
to be specified, rather than a single number for both dimensions. ::

    from PIL import ImageFilter
    ImageFilter.BoxBlur((2, 5))
    ImageFilter.GaussianBlur((2, 5))

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

EpsImagePlugin.gs_binary
^^^^^^^^^^^^^^^^^^^^^^^^

``EpsImagePlugin.gs_windows_binary`` stores the name of the Ghostscript
executable on Windows. ``EpsImagePlugin.gs_binary`` has now been added for all
platforms, and can be used to customise the name of the executable, or disable
use entirely through ``EpsImagePlugin.gs_binary = False``.

has_transparency_data
^^^^^^^^^^^^^^^^^^^^^

Images now have :py:attr:`~PIL.Image.Image.has_transparency_data` to indicate
whether the image has transparency data, whether in the form of an alpha
channel, a palette with an alpha channel, or a "transparency" key in the
:py:attr:`~PIL.Image.Image.info` dictionary.

Even if this attribute is true, the image might still appear solid, if all of
the values shown within are opaque.

ImageOps.cover
^^^^^^^^^^^^^^

Returns a resized version of the image, so that the requested size is covered,
while maintaining the original aspect ratio.

See :ref:`relative-resize` for a comparison between this and similar ``ImageOps``
methods.

size and font_size arguments when using default font
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow has had a "better than nothing" default font, which can only be drawn at
one font size. Now, if FreeType support is available, a version of
`Aileron Regular <https://dotcolon.net/fonts/aileron>`_ is loaded, which can be
drawn at chosen font sizes.

The following ``size`` and ``font_size`` arguments can now be used to specify a
font size for this new builtin font::

    ImageFont.load_default(size=24)
    draw.text((0, 0), "test", font_size=24)
    draw.textlength((0, 0), "test", font_size=24)
    draw.textbbox((0, 0), "test", font_size=24)
    draw.multiline_text((0, 0), "test", font_size=24)
    draw.multiline_textbbox((0, 0), "test", font_size=24)

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

Python 3.12
^^^^^^^^^^^

Pillow 10.0.0 had wheels built against Python 3.12 beta, available as a preview to help
others prepare for 3.12, and to ensure Pillow could be used immediately at the release
of 3.12.0 final (2023-10-02, :pep:`693`).

Pillow 10.1.0 now officially supports Python 3.12.

Added support for DDS BC5U and 8-bit color indexed images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Support has been added to read BC5U DDS files as RGB images, and
PALETTEINDEXED8 DDS files as P mode images.

Support reading signed 8-bit YCbCr TIFF images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TIFF images with unsigned integer data, 8 bits per sample and a photometric
interpretation of YCbCr can now be read.

---

### Releasenotes 10.2.0 (`docs/releasenotes/10.2.0.rst`)

10.2.0
------

Security
========

ImageFont.getmask: Applied ImageFont.MAX_STRING_LENGTH
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To protect against potential DOS attacks when using arbitrary strings as text input,
Pillow will now raise a :py:exc:`ValueError` if the number of characters passed into
:py:meth:`PIL.ImageFont.ImageFont.getmask` is over a certain limit,
:py:data:`PIL.ImageFont.MAX_STRING_LENGTH`.

This threshold can be changed by setting :py:data:`PIL.ImageFont.MAX_STRING_LENGTH`. It
can be disabled by setting ``ImageFont.MAX_STRING_LENGTH = None``.

A decompression bomb check has also been added to
:py:meth:`PIL.ImageFont.ImageFont.getmask`.

ImageFont.getmask: Trim glyph size
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To protect against potential DOS attacks when using PIL fonts,
:py:class:`PIL.ImageFont.ImageFont` now trims the size of individual glyphs so that
they do not extend beyond the bitmap image.

:cve:`2023-50447`: ImageMath.eval: Restricted environment keys
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If an attacker has control over the keys passed to the
``environment`` argument of :py:meth:`!PIL.ImageMath.eval`, they may be able to execute
arbitrary code. To prevent this, keys matching the names of builtins and keys
containing double underscores will now raise a :py:exc:`ValueError`.

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

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

``ImageFile.raise_oserror()`` has been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). The function is undocumented and is only useful for translating
error codes returned by a codec's ``decode()`` method, which ImageFile already does
automatically.

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

The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). These are 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.

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

Zero or negative font size error
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When creating a :py:class:`~PIL.ImageFont.FreeTypeFont` instance, either directly or
through :py:func:`~PIL.ImageFont.truetype`, if the font size is zero or less, a
:py:exc:`ValueError` will now be raised.

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

Added DdsImagePlugin enums
^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.DdsImagePlugin.DDSD`, :py:class:`~PIL.DdsImagePlugin.DDSCAPS`,
:py:class:`~PIL.DdsImagePlugin.DDSCAPS2`, :py:class:`~PIL.DdsImagePlugin.DDPF`,
:py:class:`~PIL.DdsImagePlugin.DXGI_FORMAT` and :py:class:`~PIL.DdsImagePlugin.D3DFMT`
enums have been added to :py:class:`PIL.DdsImagePlugin`.

JPEG RGB color space
^^^^^^^^^^^^^^^^^^^^

When saving JPEG files, ``keep_rgb`` can now be set to ``True``. This will store RGB
images in the RGB color space instead of being converted to YCbCr automatically by
libjpeg. When this option is enabled, attempting to chroma-subsample RGB images with
the ``subsampling`` option will raise an :py:exc:`OSError`.

JPEG restart marker interval
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When saving JPEG files, ``restart_marker_blocks`` and ``restart_marker_rows`` can now
be used to emit restart markers whenever the specified number of MCU blocks or rows
have been produced.

JPEG tables-only streamtype
^^^^^^^^^^^^^^^^^^^^^^^^^^^

When saving JPEG files, ``streamtype`` can now be set to 1, for tables-only. This will
output only the quantization and Huffman tables for the image.

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

Added DDS BC4U and DX10 BC1 and BC4 reading
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Support has been added to read the BC4U format of DDS images.

Support has also been added to read DX10 BC1 and BC4, whether UNORM or
TYPELESS.

Support arbitrary masks for uncompressed RGB DDS images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

All masks are now supported when reading DDS images with uncompressed RGB data,
allowing for bit counts other than 24 and 32.

Saving TIFF tag RowsPerStrip
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When saving TIFF images, the TIFF tag RowsPerStrip can now be one of the tags set by
the user, rather than always being calculated by Pillow.

Optimized ImageColor.getrgb and getcolor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The color calculations of :py:func:`~PIL.ImageColor.getrgb` and
:py:func:`~PIL.ImageColor.getcolor` are now cached using
:py:func:`functools.lru_cache`. Cached calls of ``getrgb`` are 3.1 - 91.4 times
as fast and ``getcolor`` are 5.1 - 19.6 times as fast.

Optimized ImageMode.getmode
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The lookups made by :py:func:`~PIL.ImageMode.getmode` are now cached using
:py:func:`functools.lru_cache` instead of a custom cache. Cached calls are 1.2 times as
fast.

Optimized ImageStat.Stat count and extrema
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Calculating the :py:attr:`~PIL.ImageStat.Stat.count` and
:py:attr:`~PIL.ImageStat.Stat.extrema` statistics is now faster. After the
histogram is created in ``st = ImageStat.Stat(im)``, ``st.count`` is 3 times as fast on
average and ``st.extrema`` is 12 times as fast on average.

Encoder errors now report error detail as string
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:exc:`OSError` exceptions from image encoders now include a textual description of
the error instead of a numeric error code.

Type hints
^^^^^^^^^^

Work has begun to add type annotations to Pillow, including:

* :py:mod:`~PIL.ContainerIO`
* :py:mod:`~PIL.FontFile`, :py:mod:`~PIL.BdfFontFile` and :py:mod:`~PIL.PcfFontFile`
* :py:mod:`~PIL.ImageChops`
* :py:mod:`~PIL.ImageMode`
* :py:mod:`~PIL.ImageSequence`
* :py:mod:`~PIL.ImageTransform`
* :py:mod:`~PIL.TarIO`

---

### Releasenotes 10.3.0 (`docs/releasenotes/10.3.0.rst`)

10.3.0
------

Security
========

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

.. danger::
  ``ImageMath.eval()`` uses Python's ``eval()`` function to process the expression
  string, and carries the security risks of doing so. A direct replacement for this is
  the new :py:meth:`~PIL.ImageMath.unsafe_eval`, but that carries the same risks. It is
  not recommended to process expressions without considering this.
  :py:meth:`~PIL.ImageMath.lambda_eval` is a more secure alternative.

:cve:`2024-28219`: Fix buffer overflow in ``_imagingcms.c``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In ``_imagingcms.c``, two ``strcpy`` calls were able to copy too much data into fixed
length strings. This has been fixed by using ``strncpy`` instead.

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

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

A number of constants and a function in :py:mod:`.ImageCms` have been deprecated.
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 deprecated. Use :py:meth:`~PIL.ImageMath.lambda_eval` or
:py:meth:`~PIL.ImageMath.unsafe_eval` instead. See earlier security notes for more
information.

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

Added alpha_quality argument when saving WebP images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When saving WebP images, an ``alpha_quality`` argument can be passed to the encoder. It
is an integer value between 0 to 100, where values other than 100 will provide lossy
compression.

Negative kmeans error
^^^^^^^^^^^^^^^^^^^^^

When calling :py:meth:`~PIL.Image.Image.quantize`, a negative ``kmeans`` will now
raise a :py:exc:`ValueError`, unless a palette is supplied to make the value redundant.

Negative P1-P3 PPM value error
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a P1-P3 PPM image contains a negative value, a :py:exc:`ValueError` will now be
raised.

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

Added PerspectiveTransform
^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.ImageTransform.PerspectiveTransform` has been added, meaning
that all of the :py:data:`~PIL.Image.Transform` values now have a corresponding
subclass of :py:class:`~PIL.ImageTransform.Transform`.

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

Portable FloatMap (PFM) images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Support has been added for reading and writing grayscale (Pf format)
Portable FloatMap (PFM) files containing ``F`` data.

Release GIL when fetching WebP frames
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Python's Global Interpreter Lock is now released when fetching WebP frames from
the libwebp decoder.

Type hints
^^^^^^^^^^

Pillow now has type hints for a large part of its modules, and the package
includes a ``py.typed`` file and the ``Typing :: Typed`` Trove classifier.

---

### Releasenotes 10.4.0 (`docs/releasenotes/10.4.0.rst`)

10.4.0
------

Security
========

ImageShow.WindowsViewer.show_file
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If an attacker has control over the ``path`` passed to
``ImageShow.WindowsViewer.show_file()``, they may be able to
execute arbitrary shell commands.

To prevent this, a :py:exc:`FileNotFoundError` will be raised if the ``path``
does not exist as a file. To provide a consistent experience, the error has
been added to all :py:class:`~PIL.ImageShow` viewers.

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

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

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

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 deprecated. Defaulting to "L" or "1" if the mode cannot be mapped
is also deprecated.

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

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

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

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

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

ImageDraw.circle
^^^^^^^^^^^^^^^^

Added :py:meth:`~PIL.ImageDraw.ImageDraw.circle`. It provides the same functionality as
:py:meth:`~PIL.ImageDraw.ImageDraw.ellipse`, but instead of taking a bounding box, it
takes a center point and radius.

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

Python 3.13 beta
^^^^^^^^^^^^^^^^

To help others prepare for Python 3.13, wheels have been built against the 3.13 beta as
a preview. This is not official support for Python 3.13, but simply an opportunity for
users to test how Pillow works with the beta and report any problems.

---

### Releasenotes 11.0.0 (`docs/releasenotes/11.0.0.rst`)

11.0.0
------

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

Python 3.8
^^^^^^^^^^

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

Python 3.12 on macOS <= 10.12
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The latest version of Python 3.12 only supports macOS versions 10.13 and later,
and so Pillow has also updated the deployment target for its prebuilt Python 3.12
wheels.

PSFile
^^^^^^

The :py:class:`!PSFile` class was removed in Pillow 11 (2024-10-15).
This class was only made as a helper to be used internally,
so there is no replacement. If you need this functionality though,
it is a very short class that can easily be recreated in your own code.

PyAccess and Image.USE_CFFI_ACCESS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Since Pillow's C API is now faster than PyAccess on PyPy, ``PyAccess`` has been
removed. Pillow's C API will now be used on PyPy instead.

``Image.USE_CFFI_ACCESS``, for switching from the C API to PyAccess, was
similarly removed.

TiffImagePlugin IFD_LEGACY_API
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An unused setting, ``TiffImagePlugin.IFD_LEGACY_API``, has been removed.

WebP 0.4
^^^^^^^^

Support for WebP 0.4 and earlier has been removed; WebP 0.5 is the minimum supported.

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

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

.. deprecated:: 11.0.0

Support for FreeType 2.9.0 is deprecated and will be removed in Pillow 12.0.0
(2025-10-15), when FreeType 2.9.1 will be the minimum 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/

Get internal pointers to objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

``Image.core.ImagingCore.id`` and ``Image.core.ImagingCore.unsafe_ptrs`` have been
deprecated and will be removed in Pillow 12 (2025-10-15). They were used for obtaining
raw pointers to ``ImagingCore`` internals. To interact with C code, you can use
``Image.Image.getim()``, which returns a ``Capsule`` object.

ICNS (width, height, scale) sizes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

Setting an ICNS image size to ``(width, height, scale)`` before loading has been
deprecated. Instead, ``load(scale)`` can be used.

Image isImageType()
^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

``Image.isImageType(im)`` has been deprecated. Use ``isinstance(im, Image.Image)``
instead.

ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been deprecated. One or more
keyword arguments can be used instead.

JpegImageFile.huffman_ac and JpegImageFile.huffman_dc
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

The ``huffman_ac`` and ``huffman_dc`` dictionaries on JPEG images were unused. They
have been deprecated, and will be removed in Pillow 12 (2025-10-15).

Specific WebP feature checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. deprecated:: 11.0.0

``features.check("transp_webp")``, ``features.check("webp_mux")`` and
``features.check("webp_anim")`` are now deprecated. They will always return
``True`` if the WebP module is installed, until they are removed in Pillow
12.0.0 (2025-10-15).

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

Default resampling filter for I;16* image modes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The default resampling filter for I;16, I;16L, I;16B and I;16N has been changed from
``Image.NEAREST`` to ``Image.BICUBIC``, to match the majority of modes.

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

Writing XMP bytes to JPEG and MPO
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

XMP data can now be saved to JPEG files using an ``xmp`` argument::

    im.save("out.jpg", xmp=b"test")

The data can also be set through :py:attr:`~PIL.Image.Image.info`, for use when saving
either JPEG or MPO images::

    im.info["xmp"] = b"test"
    im.save("out.jpg")

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

Python 3.13
^^^^^^^^^^^

Pillow 10.4.0 had wheels built against Python 3.13 beta, available as a preview to help
others prepare for 3.13, and to ensure Pillow could be used immediately at the release
of 3.13.0 final (2024-10-07, :pep:`719`).

Pillow 11.0.0 now officially supports Python 3.13.

Support has also been added for the experimental free-threaded mode of :pep:`703`.

Python 3.13 only supports macOS versions 10.13 and later.

C-level flags
^^^^^^^^^^^^^

Some compiling flags like ``WITH_THREADING``, ``WITH_IMAGECHOPS``, and other
``WITH_*`` were removed. These flags were not available through the build system,
but they could be edited in the C source.

---

### Releasenotes 11.1.0 (`docs/releasenotes/11.1.0.rst`)

11.1.0
------

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

ExifTags.IFD.Makernote
^^^^^^^^^^^^^^^^^^^^^^

``ExifTags.IFD.Makernote`` has been deprecated. Instead, use
``ExifTags.IFD.MakerNote``.

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

Writing XMP bytes to JPEG and MPO
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 11.0.0 added writing XMP data to JPEG and MPO images::

    im.info["xmp"] = b"test"
    im.save("out.jpg")

However, this meant that XMP data was automatically kept from an opened image,
which is inconsistent with the rest of Pillow's behaviour. This functionality
has been removed. To write XMP data, the ``xmp`` argument can still be used for
JPEG files::

    im.save("out.jpg", xmp=b"test")

To save XMP data to the second frame of an MPO image, ``encoderinfo`` can now
be used::

    second_im.encoderinfo = {"xmp": b"test"}
    im.save("out.mpo", save_all=True, append_images=[second_im])

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

Check for zlib-ng
^^^^^^^^^^^^^^^^^

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

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

Saving TIFF as BigTIFF
^^^^^^^^^^^^^^^^^^^^^^

TIFF images can now be saved as BigTIFF using a ``big_tiff`` argument::

    im.save("out.tiff", big_tiff=True)

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

Reading JPEG 2000 comments
^^^^^^^^^^^^^^^^^^^^^^^^^^

When opening a JPEG 2000 image, the comment may now be read into
:py:attr:`~PIL.Image.Image.info` for J2K images, not just JP2 images.

Saving JPEG 2000 CMYK images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

With OpenJPEG 2.5.3 or later, Pillow can now save CMYK images as JPEG 2000 files.

Minimum C version
^^^^^^^^^^^^^^^^^

C99 is now the minimum version of C required to compile Pillow from source.

zlib-ng in wheels
^^^^^^^^^^^^^^^^^

Wheels are now built against zlib-ng for improved speed. In tests, saving a PNG
was found to be more than twice as fast at higher compression levels.

---

### Releasenotes 11.2.1 (`docs/releasenotes/11.2.1.rst`)

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:: 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 :py:class:`PIL.ImageFile.ImageFile` instance.

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

``append_images`` no longer requires ``save_all``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Previously, ``save_all`` was required 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 :py:mod:`~PIL.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 :py:meth:`~PIL.ImageGrab.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 <https://arrow.apache.org/>`__ 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.

---

### Releasenotes 11.3.0 (`docs/releasenotes/11.3.0.rst`)

11.3.0
------

Security
========

:cve:`2025-48379`: Write buffer overflow on BCn encoding
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There is a heap buffer overflow when writing a sufficiently large (>64k encoded with
default settings) image in the DDS format due to writing into a buffer without checking
for available space.

This only affects users who save untrusted data as a compressed DDS image.

* Unclear how large the potential write could be. It is likely limited by process
  segfault, so it's not necessarily deterministic. It may be practically unbounded.
* Unclear if there's a restriction on the bytes that could be emitted. It's likely that
  the only restriction is that the bytes would be emitted in chunks of 8 or 16.

This was introduced in Pillow 11.2.0 when the feature was added.

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

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

The ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` has been deprecated. The
mode can be automatically determined from the object's shape and type instead.

.. note::

    Since pixel values do not contain information about palettes or color spaces, part
    of this functionality was restored in Pillow 12.0.0. The parameter can be used to
    place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
    example.

Saving I mode images as PNG
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In order to fit the 32 bits of I mode images into PNG, when PNG images can only contain
at most 16 bits for a channel, Pillow has been clipping the values. Rather than quietly
changing the data, this is now deprecated. Instead, the image can be converted to
another mode before saving::

    from PIL import Image
    im = Image.new("I", (1, 1))
    im.convert("I;16").save("out.png")

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

Added QOI saving
^^^^^^^^^^^^^^^^

Support has been added for saving QOI images. ``colorspace`` can be used to specify the
colorspace as sRGB with linear alpha, e.g. ``im.save("out.qoi", colorspace="sRGB")``.
By default, all channels will be linear.

Support using more screenshot utilities with ImageGrab on Linux
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.ImageGrab.grab` is now able to use GNOME Screenshot, grim or Spectacle
on Linux in order to take a snapshot of the screen.

Do not build against libavif < 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow only supports libavif 1.0.0 or later. In order to prevent errors when building
from source, if a user happens to have an earlier libavif on their system, Pillow will
now ignore it.

AVIF support in wheels
^^^^^^^^^^^^^^^^^^^^^^

Support for reading and writing AVIF images is now included in Pillow's wheels, except
for Windows ARM64 and iOS. libaom is available as an encoder and dav1d as a decoder.
(Thank you Frankie Dintino and Andrew Murray!)

iOS
^^^

Pillow now provides wheels that can be used on iOS ARM64 devices, and on the iOS
simulator on ARM64 and x86_64. Currently, only Python 3.13 wheels are available.
(Thank you Russell Keith-Magee and Andrew Murray!)

Python 3.14 beta
^^^^^^^^^^^^^^^^

To help other projects prepare for Python 3.14, wheels are now built for the
3.14 beta as a preview. This is not official support for Python 3.14, but rather
an opportunity for you to test how Pillow works with the beta and report any
problems.

---

### Releasenotes 12.0.0 (`docs/releasenotes/12.0.0.rst`)

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>`__.

---

### Releasenotes 12.1.0 (`docs/releasenotes/12.1.0.rst`)

12.1.0
------

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

Image getdata()
^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.Image.getdata` has been deprecated.
:py:meth:`~PIL.Image.Image.get_flattened_data` can be used instead. This new method is
identical, except that it returns a tuple of pixel values, instead of an internal
Pillow data type.

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

ImageMorph build_default_lut()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To match the behaviour of :py:meth:`~PIL.ImageMorph.LutBuilder.build_lut`,
:py:meth:`~PIL.ImageMorph.LutBuilder.build_default_lut()` now returns the new LUT.

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

Image get_flattened_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.Image.get_flattened_data` is identical to the deprecated
:py:meth:`~PIL.Image.Image.getdata`, except that the new method returns a tuple of
pixel values, instead of an internal Pillow data type.

Specify window in ImageGrab on macOS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When using :py:meth:`~PIL.ImageGrab.grab`, a specific window can now be selected on
macOS in addition to Windows. On macOS, this is a CGWindowID::

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

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

Added MorphOp support for 1 mode images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.ImageMorph.MorphOp` now supports both 1 mode and L mode images.

---

### Releasenotes 12.1.1 (`docs/releasenotes/12.1.1.rst`)

12.1.1
------

Security
========

:cve:`2026-25990`: Fix OOB write with invalid tile extents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check that tile extents do not use negative x or y offsets when decoding or encoding,
and raise an error if they do, rather than allowing an OOB write.

An out-of-bounds write may be triggered when opening a specially crafted PSD image.
This only affects Pillow >= 10.3.0. Reported by
`Yarden Porat <https://github.com/yardenporat353>`__.

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

Patch libavif for svt-av1 4.0 compatibility
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A patch has been added to ``depends/install_libavif.sh``, to allow libavif 1.3.0 to be
compatible with the recently released svt-av1 4.0.0.

---

### Releasenotes 12.2.0 (`docs/releasenotes/12.2.0.rst`)

12.2.0
------

Security
========

:cve:`2026-40192`: Prevent FITS decompression bomb
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When decompressing GZIP data from a FITS image, Pillow did not limit the amount of data
being read, meaning that it was vulnerable to GZIP decompression bombs. This was
introduced in Pillow 10.3.0.

The data being read is now limited to only the necessary amount.

:cve:`2026-42311`: Fix OOB write with invalid tile extents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 12.1.1 addressed :cve:`2026-25990` by improving checks for tile extents to
prevent an OOB write from specially crafted PSD images in Pillow >= 10.3.0. However,
these checks did not consider integer overflow. This has been corrected.

:cve:`2026-42310`: Prevent PDF parsing trailer infinite loop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When parsing a PDF, if a trailer refers to itself, or a more complex cyclic loop
exists, then an infinite loop occurs. Pillow now keeps a record of which trailers it
has already processed. PdfParser was added in Pillow 5.1.0.

:cve:`2026-42308`: Integer overflow when processing fonts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a font advances for each glyph by an exceedingly large amount, when Pillow keeps
track of the current position, it may lead to an integer overflow. This has been fixed.

:cve:`2026-42309`: Heap buffer overflow with nested list coordinates
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Passing nested lists as coordinates to APIs that accept coordinates such as
``ImagePath.Path``, :py:meth:`~PIL.ImageDraw.ImageDraw.polygon`
and :py:meth:`~PIL.ImageDraw.ImageDraw.line` could cause a heap buffer overflow,
as nested lists were recursively unpacked beyond the allocated buffer.
Coordinate lists are now validated to contain exactly two numeric coordinates.
This was introduced in Pillow 11.2.1.

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

Error when encoding an empty image
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Attempting to encode an image with zero width or height would previously raise
a :py:exc:`SystemError`. That has now been changed to a :py:exc:`ValueError`.

This does not add any new errors. SGI, ICNS and ICO formats are still able to
save (0, 0) images.

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

FontFile.to_imagefont()
^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.FontFile.FontFile` instances can now be directly converted to
:py:class:`~PIL.ImageFont.ImageFont` instances::

    >>> from PIL import PcfFontFile
    >>> with open("Tests/fonts/10x20-ISO8859-1.pcf", "rb") as fp:
    ...   pcffont = PcfFontFile.PcfFontFile(fp)
    ...   pcffont.to_imagefont()
    ...
    <PIL.ImageFont.ImageFont object at 0x10457bb80>

ImageText.Text.wrap
^^^^^^^^^^^^^^^^^^^

:py:meth:`.ImageText.Text.wrap` has been added, to wrap text to fit within a given
width::

    from PIL import ImageText
    text = ImageText.Text("Hello World!")
    text.wrap(50)
    print(text.text)  # "Hello\nWorld!"

or within a certain width and height, returning a new :py:class:`.ImageText.Text`
instance if the text does not fit::

    text = ImageText.Text("Text does not fit within height")
    print(text.wrap(50, 25).text == " within height")
    print(text.text)  # "Text does\nnot fit"

or scaling, optionally with a font size limit::

    text.wrap(50, 15, "shrink")
    text.wrap(50, 15, ("shrink", 7))
    text.wrap(58, 10, "grow")
    text.wrap(50, 50, ("grow", 12))

EXIF tag FrameRate
^^^^^^^^^^^^^^^^^^

The EXIF tag ``FrameRate`` has been added.

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

Support reading JPEG2000 images with CMYK palettes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

JPEG2000 images with CMYK palettes can now be read. This is the first integration of
CMYK palettes into Pillow.

Lazy plugin loading
^^^^^^^^^^^^^^^^^^^

When opening or saving an image, Pillow now lazily loads only the required plugin
based on the file extension, instead of importing all plugins upfront. This makes
``open`` 2.3-15.6x faster and ``save`` 2.2-9x faster for common formats.

Thread safety for free-threaded Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Critical sections are now used to protect FreeType font objects, improving thread
safety when using fonts in the free-threaded build of Python.

---

### Releasenotes 12.3.0 (`docs/releasenotes/12.3.0.rst`)

12.3.0
------

Security
========

:cve:`2026-59200`: Prevent decompression bomb when parsing PDF
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When parsing a PDF, ``PdfStream.decode()`` attempts to decompress data without any
limit. A default maximum of ``ImageFile.SAFEBLOCK`` has been added. ``PdfParser`` was
added in Pillow 5.1.0. Reported by `redyank <https://github.com/redyank>`__.

:cve:`2026-55798`: WindowsViewer.get_command injection
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If an attacker has control over the path passed to
``ImageShow.WindowsViewer.get_command()``, and the result is executed by the user, the
attacker may be able to execute arbitrary shell commands. Reported by Bin Luo,
University of Electronic Science and Technology of China (luob87709@gmail.com).

:cve:`2026-59203`: EPS image infinite loop
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a negative byte count is specified for the BeginBinary byte count, an infinite loop
is possible as Pillow seeks repeatedly backwards. This value will now be validated.
BeginBinary parsing was only added in Pillow 12.0.0. Reported by
`jiagongzheng-stack <https://github.com/jiagongzheng-stack>`__.

:cve:`2026-59204`: JPEG2000 image memory usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The total component width was incorrectly accumulated across tiles within a JPEG2000
image, potentially leading to excessive memory use. This was introduced as part of an
earlier security fix in Pillow 8.2.0, but has now been fixed. Reported by Fr3v1.

:cve:`2026-54058`: McIdas out-of-bounds (OOB) read
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

McIdas images can specify the stride, and if incorrectly set, may cause an OOB read.
This has been fixed. Reported by Devansh Shah, RUDRA Cybersecurity Pvt. Ltd.

:cve:`2026-59198`: Out-of-bounds (OOB) read when saving 1 mode TGA images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Saving 1 mode images as TGA with run-length encoding can trigger an OOB read. This was
added in Pillow 5.2.0, but the functionality is not possible under the TGA
specification, so it has been removed. Reported by
`Seratov <https://github.com/Seratov>`__.

:cve:`2026-59197`: Out-of-bounds (OOB) write from large RankFilter sizes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.ImageFilter.RankFilter`, and its subclasses, can potentially write
out-of-bounds if given a large size. This has been fixed. Reported by
`Seratov <https://github.com/Seratov>`__.

:cve:`2026-59199`: Out-of-bounds (OOB) write from ``Image.paste()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Large paste box dimensions can cause an OOB write in ``Image.crop()``,
``Image.paste()`` and ``Image.alpha_composite()``. This has been fixed. Reported by
`Seratov <https://github.com/Seratov>`__.

:cve:`2026-59205`: Out-of-bounds (OOB) write in ``ImageCmsTransform``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Apply a transform mode to a different image mode can trigger an OOB write in
``ImageCmsTransform``. Errors are now raised if the mode does not match. Reported by
`Seratov <https://github.com/Seratov>`__.

:cve:`2026-54059`, :cve:`2026-54060`, :cve:`2026-55379`: Prevent FontFile decompression bomb
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Decompression bomb checks have now been added to :py:class:`~PIL.FontFile.FontFile`,
and its subclasses, checking the width and height of characters. Reported by Rahul
Singh and Dinesh.

:cve:`2026-55380`: Prevent GD decompression bomb
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A decompression bomb check has been added to :py:class:`~PIL.GdImageFile.GdImageFile`.
This is format must be explicitly called though, rather than being accessible from
``Image.open()``. Reported by Rahul Singh.

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

Added ``scale_down`` argument to ``ImageGrab.grab()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.ImageGrab.grab` now accepts an optional keyword argument of
``scale_down``. This affects macOS screenshots with a ``bbox`` on a Retina screen. By
default, images will be captured at 2x. If ``scale_down`` is ``True``, they will be at
1x.

Previously, macOS screenshots with a ``bbox`` were captured at 1x by default.

Added ``max_length`` argument to ``PdfStream.decode()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When calling ``PdfStream.decode()``, the maximum length of data to decode can now be
specified. This will default to ``ImageFile.SAFEBLOCK``.

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

Python 3.15 beta
^^^^^^^^^^^^^^^^

To help other projects prepare for Python 3.15, wheels are now built for the 3.15 beta
as a preview. This is not official support for Python 3.15, but rather an opportunity
for you to test how Pillow works with the beta and report any problems.

SBOM in wheels
^^^^^^^^^^^^^^

Following :pep:`770`, the Software Bill-of-Materials (SBOM) has now been embedded into
Pillow's wheels.

Removed Python 3.13 free-threaded wheels
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Python 3.13 added an experimental free-threaded mode, and Pillow 11.0.0 added
corresponding wheels. Now that Python 3.14 includes official support for it, Pillow has
removed wheels for Python 3.13 free-threaded mode.

Performance improvements
^^^^^^^^^^^^^^^^^^^^^^^^

A number of changes have been made to optimize the use of C when manipulating images.
This improves performance by up to 5.6 times of ``Image``'s
``alpha_composite``, ``fill``, ``filter``, ``getchannel``, ``linear_gradient``,
``matrix``, ``merge``, ``negative``, ``putalpha``, ``quantize``,
``radial_gradient``, ``resample``, ``split``, and ``ImageChops`` operations.

---

### Releasenotes 13.0.0 (`docs/releasenotes/13.0.0.rst`)

13.0.0
------

Security
========

CVE identifiers will be added to these entries as they are assigned.

Critical
^^^^^^^^

* :cve:`2026-96639`, :ghsa:`v9pv-5gc8-w2m6`: Stale native image storage reused after mode transitions
* :cve:`2026-112398`, :cve:`2026-112403`, :ghsa:`5x8w-8jj5-q52h`, :ghsa:`8g5g-8vmr-9782`: JPEG decoder buffer overflow from scanlines wider than tile extents

High
^^^^

* :cve:`2026-96644`, :ghsa:`9v9v-9qvf-h2hj`: WMF/EMF heap out-of-bounds read from dimension truncation
* :cve:`2026-96637`, :ghsa:`g842-9rc4-69pw`: SPIDER decompression bomb bypass via seek()
* :cve:`2026-96643`, :ghsa:`g4qv-2jxx-769h`: Unbounded Exif header replacement loop
* :cve:`2026-96778`, :ghsa:`g7cr-3p24-7wf7`: JPEG comment write after ICC profile fills encoder buffer
* :cve:`2026-112395`, :cve:`2026-112404`, :ghsa:`462x-pgg6-55fp`, :ghsa:`c6hw-5grf-ff96`: TIFF tile and YCbCr decoding out-of-bounds read from undersized libtiff buffers
* :cve:`2026-112895`, :ghsa:`p4wg-p73j-c528`: PDF parsing stack exhaustion from long trailer chains and deep or cyclic page trees
* :cve:`2026-96640`, :ghsa:`mrfp-p49p-3hf2`: PDF append resource exhaustion from repeated page tree references
* :cve:`2026-112896`, :ghsa:`pchr-8j38-3x4p`: TIFF encoder accepted an incorrectly sized Colormap for non-8-bit images
* :cve:`2026-112393`, :ghsa:`332p-7hrc-92wf`: TIFF encoder heap buffer overflow when saving to a file object
* :ghsa:`xcvg-w56q-r89m`: TIFF encoder heap buffer overflow when tags override the image size
* :cve:`2026-112902`, :ghsa:`xvh5-g6gv-559v`: TIFF encoder memory disclosure and crash from mismatched tag values
* :cve:`2026-112897`, :ghsa:`q45j-58j2-45rg`: TIFF decoding returned uninitialized memory for short JPEG strips
* :ghsa:`78g4-xqwv-q3g8`: Bundled OpenJPEG heap buffer overflow when reading tile-part data

Medium
^^^^^^

* :cve:`2026-112396`, :ghsa:`4rr5-89j8-mwwm`: TIFF encoder use-after-free write
* :cve:`2026-96636`, :ghsa:`p8hx-v2p6-rp84`: MPO, DCX and MIC decompression bomb bypass via seek()
* :cve:`2026-112406`, :ghsa:`f2g6-542v-9j58`: PDF page tree stack exhaustion via cyclic ``/Kids`` reference
* :cve:`2026-112399`, :ghsa:`5xm2-6676-qcp9`: APNG decompression bomb bypass via delayed disposal-frame sizing
* :cve:`2026-96642`, :ghsa:`3j72-p6qg-6xp7`: TarIO negative size field causes infinite CPU-spin loop
* :cve:`2026-96638`, :ghsa:`24rc-8hj2-v98c`: BMP RLE decoder memory-amplification denial of service
* :cve:`2026-112892`, :ghsa:`gg2r-wvfm-q9rx`: MSP RLE decoder expands a tiny file into unbounded memory
* :ghsa:`wqgw-9xfh-qf2g`: TIFF and Exif IFD parsing memory and CPU amplification from shared tag data
* :cve:`2026-112894`, :ghsa:`jg86-v3jv-hrpm`: Quadratic time when writing many objects to a PDF
* :cve:`2026-112391`, :ghsa:`254f-3936-288h`: PdfParser unbounded recursion via deeply nested objects
* :cve:`2026-112898`, :ghsa:`rfgq-q3w2-pmv2`: Image.quantize() crash from an empty target palette
* :cve:`2026-112901`, :ghsa:`xgh8-jp6q-p5x8`: XBM header parsing regular expression denial of service
* :cve:`2026-112390`, :cve:`2026-112401`, :cve:`2026-112891`, :ghsa:`22hg-r758-rrw9`, :ghsa:`74r2-7ff9-mjj2`, :ghsa:`fc9g-5qg7-mf45`: GIF comment handling quadratic-time blowup from repeated concatenation
* :cve:`2026-112392`, :ghsa:`27h8-gf7j-v5hc`: Out-of-bounds read in rank-based filters for zero-dimension images
* :cve:`2026-96641`, :ghsa:`4rm8-3hmm-39fg`: Integer underflow in PILfont text width calculation
* :cve:`2026-112405`, :ghsa:`cp9v-662q-vvx9`: Image.merge() buffer overflow when merging 32-bit images as narrower bands
* :cve:`2026-112893`, :ghsa:`j4m9-6w36-pw47`: Uninitialized glyph pointer freed on font rendering error path
* :cve:`2026-112402`, :ghsa:`7mwm-ghpf-9vrm`: Double free in ``Image.transform()`` after an allocation failure
* :cve:`2026-112394`, :ghsa:`4558-3h8r-v8xp`: ``P;2L`` and ``P;4L`` raw mode decoders read past the end of their input
* :cve:`2026-112900`, :ghsa:`w889-685w-c8fh`: EPS filename argument injection into Ghostscript
* :cve:`2026-114501`, :ghsa:`654x-cwwv-5j9c`: Arrow export leaks stale heap memory when ``PILLOW_ALIGNMENT`` > 1

Low
^^^

* :cve:`2026-112400`, :ghsa:`65qm-jvmh-6pqg`: GIF decompression bomb check used a size discarded on failure
* :cve:`2026-112899`, :ghsa:`vx6w-vv9f-6gvg`: EPS decompression bomb bypass via Ghostscript rendering
* :cve:`2026-112397`, :ghsa:`58r4-6rv3-gfh8`: ImageMorph.MorphOp.apply() out-of-bounds write on zero-width images

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

Python 3.10
^^^^^^^^^^^

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

Saving I mode images as PNG
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In order to fit the 32 bits of I mode images into PNG, when PNG images can only contain
at most 16 bits for a channel, Pillow has been clipping the values. Rather than quietly
changing the data, this is now removed. Instead, the image can be converted to another
mode before saving::

    from PIL import Image
    im = Image.new("I", (1, 1))
    im.convert("I;16").save("out.png")

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

Using the ``mode`` parameter in :py:meth:`~PIL.Image.fromarray()` was deprecated in
Pillow 11.3.0. In Pillow 12.0.0, this was partially reverted, and now the only
functionality removed is when the mode changes data types. Since pixel values do not
contain information about palettes or color spaces, the parameter can still be used to
place grayscale L mode data within a P mode image, or read RGB data as YCbCr for
example. If omitted, the mode will be automatically determined from the object's shape
and type.

Image.Image.get_child_images()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``Image.Image.get_child_images()`` has been 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 :py:class:`PIL.ImageFile.ImageFile`
instance.

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

``Image._show`` has been removed. 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 removed. They were set to ``None`` since Pillow
2.3.0.

ExifTags.IFD.Makernote
^^^^^^^^^^^^^^^^^^^^^^

``ExifTags.IFD.Makernote`` has been removed. Instead, use ``ExifTags.IFD.MakerNote``.

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

IM image format
^^^^^^^^^^^^^^^

The IM image format has been deprecated and removal is planned in Pillow 15.0.0
(2028-10-15). If you are using this format and would like to continue doing so,
open an issue about what other software uses it.

JpegImageFile.load_djpeg
^^^^^^^^^^^^^^^^^^^^^^^^

``JpegImageFile.load_djpeg`` has been deprecated, and will be removed in Pillow 14
(2027-10-15).

Use the built-in JPEG decoder instead, or call ``djpeg`` directly and decode the
resulting image with Pillow.

ImageQt align8to32()
^^^^^^^^^^^^^^^^^^^^

``ImageQt.align8to32()`` has been deprecated. This was an undocumented helper function
intended for internal use, so there is no replacement.

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

ImageColor.getcolor() with premultiplied alpha modes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When ``mode`` is ``RGBa`` or ``La``, :py:func:`~PIL.ImageColor.getcolor` now returns
color values premultiplied by the alpha channel, matching how pixels are stored in
those modes. Previously, the unmultiplied values were returned.

Duplicate TIFF tags
^^^^^^^^^^^^^^^^^^^

If a TIFF IFD contains the same tag more than once, the first value is now kept.
Previously, the last value overwrote the earlier ones.

Saving small ICO images
^^^^^^^^^^^^^^^^^^^^^^^

When saving an image smaller than 16x16 pixels as an ICO without a ``sizes``
argument, the image's own size is now used. Previously, none of the default sizes
matched, and an ICO containing no images was written. If no size in ``sizes`` fits
within the image, a :py:exc:`ValueError` is now raised.

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

New resizing filters
^^^^^^^^^^^^^^^^^^^^

Two new filters are available for :py:meth:`~PIL.Image.Image.resize` and
:py:meth:`~PIL.Image.Image.thumbnail`: ``Image.Resampling.MKS2013`` and
``Image.Resampling.MKS2021``. These are versions of the Magic Kernel Sharp filter.

Added ``strip_namespaces`` argument to ``Image.getxmp()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.Image.Image.getxmp` now accepts an optional keyword argument of
``strip_namespaces``. It is set to ``True`` by default, stripping each tag's XML
namespace URI prefix as before. If set to ``False``, each tag's full
``{namespace-uri}local-name`` form is kept instead, avoiding collisions between tags
that share a local name across different namespaces.

Added ``escape`` argument to ``PSDraw.text()``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.PSDraw.PSDraw.text` now accepts a keyword-only boolean argument,
``escape``. Set it to ``True`` to escape backslashes, for example in Windows paths.
The default, ``False``, preserves the existing handling of backslashes and PostScript
escape sequences.

ImageOps invert, posterize and solarize of P images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:func:`~PIL.ImageOps.invert`, :py:func:`~PIL.ImageOps.posterize` and
:py:func:`~PIL.ImageOps.solarize` now support P mode images. The operation is applied
to the palette colors, leaving any alpha values in the palette unchanged. Previously,
these functions raised :py:exc:`NotImplementedError` for P mode.

Path-like objects for font files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:func:`~PIL.ImageFont.load`, :py:func:`~PIL.ImageFont.load_path` and
:py:meth:`~PIL.FontFile.FontFile.save` now accept :py:class:`os.PathLike` objects,
such as :py:class:`pathlib.Path`, in addition to strings.

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

Python 3.15
^^^^^^^^^^^

Pillow 12.3.0 had wheels built against Python 3.15 beta, available as a preview
to help projects prepare for 3.15, and to ensure Pillow could be used
immediately at the release of 3.15.0 final (2026-10-01, :pep:`790`).

Pillow 13.0.0 now officially supports Python 3.15.

Faster import
^^^^^^^^^^^^^

Importing Pillow takes around half the time it did in Pillow 12.3.0. ``PIL.Image`` no
longer imports ``logging``, modules that are only needed for some operations, such as
``tempfile``, are now imported on first use, and on Python 3.15 Pillow also declares
``__lazy_modules__`` to defer its remaining standard library imports (:pep:`810`). On an
Apple Silicon Mac, ``from PIL import Image`` took 24 ms on Python 3.14 and 23 ms on
Python 3.15 with Pillow 12.3.0, and now takes 12 ms and 10 ms.

PyPy 3.12
^^^^^^^^^

Wheels are now also built for PyPy 3.12, in addition to PyPy 3.11.

Faster JPEG 2000, TIFF, FreeType and LittleCMS in macOS and Linux wheels
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Several of the libraries bundled in the macOS and Linux wheels were built without
compiler optimisation. The Windows wheels were not affected.

These libraries are now compiled with ``-O2``. Compared to Pillow 12.3.0, the wheels

* decode JPEG 2000 images 2 to 3 times faster and encode them about twice as fast,
* read and write LZW-compressed TIFF images about twice as fast,
* render text with :py:mod:`~PIL.ImageFont` up to 3 times faster, and
* apply :py:mod:`~PIL.ImageCms` transforms up to 3 times faster.

PNG, JPEG, WebP and AVIF are unaffected, as those libraries were already built with
optimisation.

Performance improvements
^^^^^^^^^^^^^^^^^^^^^^^^

Building on the optimizations in Pillow 12.3.0, more of the C code has been
restructured so that compilers can vectorize it. Compared to Pillow 12.3.0,
:py:func:`~PIL.ImageChops.offset` is up to 46 times faster,
:py:meth:`~PIL.Image.Image.getbbox` up to 24 times faster,
flipping and rotating by 180 degrees with
:py:meth:`~PIL.Image.Image.transpose` up to 10 times faster,
:py:meth:`~PIL.Image.Image.filter` up to 3.5 times faster,
:py:func:`~PIL.ImageChops.difference` up to 3 times faster, and converting P and PA
images to RGB and RGBA up to 2.5 times faster. Saving an optimized GIF with a shared
palette is around 6 times faster and uses less memory.

Wheels now use HarfBuzz for hinting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

FreeType can use HarfBuzz to work out which glyphs a script covers,
so that its auto-hinter can derive hinting "Blue Zones" for scripts such as Arabic.

Only the Windows wheels were actually built with this support.
The macOS wheels disabled HarfBuzz interoperability outright,
and the Linux wheels left it up to FreeType's ``configure``,
which in turn fell back to loading HarfBuzz by its unversioned name at
runtime.

Since the bundled copy of HarfBuzz is renamed when the wheel is audited and repaired
for distribution, that lookup only succeeded if a separate copy happened to be
installed on the system with the expected name (e.g. ``libharfbuzz.so.0``).

All wheels are now linked against the HarfBuzz that Pillow ships,
which may slightly change how text is rendered in scripts that rely on the auto-hinter.

Thread safety for free-threaded Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Critical sections now protect most operations on core image objects, such as
conversion, pasting, filtering and pixel access, improving thread safety in the
free-threaded build of Python. AVIF decoding also no longer blocks other threads.

Resizing images with alpha
^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``reducing_gap`` argument to :py:meth:`~PIL.Image.Image.resize` is now
applied to RGBA and LA images. Previously, these modes ignored the argument,
including when called by :py:meth:`~PIL.Image.Image.thumbnail`, which uses
``reducing_gap=2.0`` by default.

Preserved transparency when padding or expanding images in ImageOps
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:func:`~PIL.ImageOps.pad` and :py:func:`~PIL.ImageOps.expand` now preserve the
``transparency`` value from the source image's ``info`` dictionary. Transparent
pixels in L, P and RGB images previously became opaque when a border was added.
New palette colors are allocated without using reserved transparency entries.

Fixed reading FITS images with more than 8 bits per pixel
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

FITS data is big-endian, but Pillow was reading 16-bit and 32-bit integer data, and
32-bit and 64-bit floating point data, in the native byte order. These images now
load with the correct pixel values.

Fixed accuracy of 16-bit image filters and conversions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Applying a kernel filter to an ``I;16`` image gave incorrect results for pixel values
above 255, and converting an ``I;16N`` image to ``I`` or ``F`` clipped values to 255.
Both now preserve the full 16-bit range.

Saving APNG frames with different palettes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An APNG file can only contain a single palette. When saving P mode frames with
different palettes, the image is now saved as RGB, or RGBA if any palette contains
alpha, instead of writing the later frames with the wrong colors.

Fixed ImageStat variance rounding
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Fixed a floating-point rounding error that may have produced a negative variance in
:py:attr:`~PIL.ImageStat.Stat.var`.

Fixed ImageChops.offset() for 16-bit images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.ImageChops.offset` now works correctly for 16-bit-per-channel images.

Fixed drawing on I;16B images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When drawing on an ``I;16B`` image, some drawing methods wrote in the wrong byte order.
All drawing operations now use the byte order of the image mode.

Fixed histograms for masked LA, La and PA images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When :py:meth:`~PIL.Image.Image.histogram` was given a mask for a two-band image (LA,
La or PA), the second band was incorrectly derived from the first band of the input
image, rather than the alpha band.

Fixed exporting Arrow arrays from images with non-contiguous rows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exporting an image as an Arrow array assumed that its rows were contiguous. However,
this was not the case for

* images whose rows were padded to an alignment returned incorrect data,
* empty images,
* images created by :py:func:`~PIL.Image.frombuffer`, and
* images memory-mapped from uncompressed files.

These images crashed instead.

Images with rows that are not contiguous now raise a :py:exc:`ValueError`, and the
others are exported correctly.

Fixed combining GIF frames with missing durations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Saving identical consecutive GIF frames no longer raises a ``KeyError`` when an earlier
frame has no duration and a later frame does.

PNG palettes are no longer padded when saving with the ``bits`` argument
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When saving a ``P`` mode image as a PNG with the ``bits`` argument, Pillow used to pad
the ``PLTE`` chunk with zeroes up to ``2 ** bits`` entries. The ``PLTE`` chunk now only
contains as many entries as the image's palette actually has, matching the behavior
already used when ``bits`` is not specified.

Restore image position if ImageSequence.all_frames() fails
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If processing a frame in :py:func:`~PIL.ImageSequence.all_frames` raises an exception,
the given image will now seek back to its original frame.

Clean up TIFF encoders before closing their output files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TIFF saving now explicitly cleans up the libtiff encoder, including when saving
raises an exception. Previously, delayed encoder destruction could access a closed
file descriptor after it had been reused for another file, disturbing that file's
position or contents.

:py:meth:`~PIL.Image.Image.tobytes` also now explicitly cleans up its encoder on
both success and failure, rather than relying on object destruction.

Fixed reading PSD layers at the wrong file offset
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When seeking to a layer of a PSD image, the pixel data was read from the wrong
position in the file, so :py:meth:`~PIL.Image.Image.seek` returned unrelated
bytes reinterpreted as image data instead of that layer's actual content.

Fixed opening XBM images with comments
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

XBM images with C-style ``/* ... */`` comments in the header could not be identified.
Comments on separate lines before the bits declaration are now skipped.

Clarified FriBiDi shim license
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The SBOM published with Pillow 12.3.0 listed the vendored FriBiDi shim
(``src/thirdparty/fribidi-shim/``) as LGPL-2.1-or-later. The shim was written for
Pillow and is covered by Pillow's MIT-CMU license. Its header declares the parts of
FriBiDi's public API needed to load FriBiDi at runtime, and contains no FriBiDi code.
FriBiDi itself is not included in Pillow's wheels.

The shim's source files now include SPDX license identifiers, and the SBOM has been
corrected.

ImagePath.Path.compact() on an empty path
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`~PIL.ImagePath.Path.compact` is documented to return the number of
points removed. On a path with no points, it instead added a point whose
y coordinate was read from uninitialized memory, and returned ``-1``.
``compact()`` now leaves an empty path unchanged and returns ``0``.

---

### Releasenotes 13.1.0 (`docs/releasenotes/13.1.0.rst`)

13.1.0
------

Security
========

TODO
^^^^

TODO

:cve:`YYYY-XXXXX`: TODO
^^^^^^^^^^^^^^^^^^^^^^^

TODO

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

TODO
^^^^

TODO

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

TODO
^^^^

TODO

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

TODO
^^^^

TODO

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

TODO
^^^^

TODO

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

Resizing I;16B and I;16N images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

On little-endian systems, :py:meth:`~PIL.Image.Image.resize` read and wrote
I;16B and I;16N pixel values in the wrong byte order when using a resampling
filter other than ``Resampling.NEAREST``. This has been fixed.

Blurring I;16 images
^^^^^^^^^^^^^^^^^^^^

:py:class:`~PIL.ImageFilter.GaussianBlur` and :py:class:`~PIL.ImageFilter.BoxBlur`
now support I;16, I;16L, I;16B and I;16N images.

---

### Releasenotes 2.3.1 (`docs/releasenotes/2.3.1.rst`)

2.3.1
-----

Security
========

These issues were reported in
`Debian bug #737059 <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=737059>`_.

:cve:`2014-1932`: Fix insecure use of :py:func:`tempfile.mktemp`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The (1) ``load_djpeg`` function in ``JpegImagePlugin.py``, (2) Ghostscript function
in ``EpsImagePlugin.py``, (3) ``load`` function in ``IptcImagePlugin.py``, and (4)
``_copy`` function in ``Image.py`` in
Pillow before 2.3.1 do not properly create temporary files, which allow
local users to overwrite arbitrary files and obtain sensitive information via a
symlink attack on the temporary file.

:cve:`2014-1933`: Fix insecure use of :py:func:`tempfile.mktemp`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The (1) ``JpegImagePlugin.py`` and (2) ``EpsImagePlugin.py`` scripts in
Pillow before 2.3.1 uses the names of
temporary files on the command line, which makes it easier for local users to
conduct symlink attacks by listing the processes.

---

### Releasenotes 2.3.2 (`docs/releasenotes/2.3.2.rst`)

2.3.2
-----

Security
========

:cve:`2014-3589`: Fix DOS attack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
block size.

Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.

---

### Releasenotes 2.5.2 (`docs/releasenotes/2.5.2.rst`)

2.5.2
-----

Security
========

:cve:`2014-3589`: Fix DOS attack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
block size.

Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.

---

### Releasenotes 2.6.0 (`docs/releasenotes/2.6.0.rst`)

2.6.0
-----

Security
========

:cve:`2014-3589`: Fix DOS attack
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``PIL/IcnsImagePlugin.py`` in Pillow before 2.3.2 and
2.5.x before 2.5.2 allows remote attackers to cause a denial of service via a crafted
block size.

Found and reported by Andrew Drake of `Dropbox <https://www.dropbox.com/>`__.

---

### Releasenotes 2.7.0 (`docs/releasenotes/2.7.0.rst`)

2.7.0
-----

Sane plugin
^^^^^^^^^^^

The Sane plugin has now been split into its own repo:
https://github.com/python-pillow/Sane .

PNG text chunk size limits
^^^^^^^^^^^^^^^^^^^^^^^^^^

To prevent potential denial of service attacks using compressed text
chunks, there are now limits to the decompressed size of text chunks
decoded from PNG images. If the limits are exceeded when opening a PNG
image a :py:exc:`ValueError` will be raised.

Individual text chunks are limited to
:py:attr:`PIL.PngImagePlugin.MAX_TEXT_CHUNK`, set to 1MB by
default. The total decompressed size of all text chunks is limited to
:py:attr:`PIL.PngImagePlugin.MAX_TEXT_MEMORY`, which defaults to
64MB. These values can be changed prior to opening PNG images if you
know that there are large text blocks that are desired.

Image resizing filters
^^^^^^^^^^^^^^^^^^^^^^

Image resizing methods :py:meth:`~PIL.Image.Image.resize` and
:py:meth:`~PIL.Image.Image.thumbnail` take a ``resample`` argument, which tells
which filter should be used for resampling. Possible values are:
``NEAREST``, ``BILINEAR``, ``BICUBIC`` and ``ANTIALIAS``. Almost all of them
were changed in this version.

Bicubic and bilinear downscaling
++++++++++++++++++++++++++++++++

From the beginning ``BILINEAR`` and ``BICUBIC`` filters were based on affine
transformations and used a fixed number of pixels from the source image for
every destination pixel (2x2 pixels for ``BILINEAR`` and 4x4 for ``BICUBIC``).
This gave an unsatisfactory result for downscaling. At the same time, a high
quality convolutions-based algorithm with flexible kernel was used for
``ANTIALIAS`` filter.

Starting from Pillow 2.7.0, a high quality convolutions-based algorithm is used
for all of these three filters.

If you have previously used any tricks to maintain quality when downscaling with
``BILINEAR`` and ``BICUBIC`` filters (for example, reducing within several
steps), they are unnecessary now.

Antialias renamed to Lanczos
++++++++++++++++++++++++++++

A new ``LANCZOS`` constant was added instead of ``ANTIALIAS``.

When ``ANTIALIAS`` was initially added, it was the only high-quality filter
based on convolutions. It's name was supposed to reflect this. Starting from
Pillow 2.7.0 all resize method are based on convolutions. All of them are
antialias from now on. And the real name of the ``ANTIALIAS`` filter is Lanczos
filter.

The ``ANTIALIAS`` constant is left for backward compatibility and is an alias
for ``LANCZOS``.

Lanczos upscaling quality
+++++++++++++++++++++++++

The image upscaling quality with ``LANCZOS`` filter was almost the same as
``BILINEAR`` due to a bug. This has been fixed.

Bicubic upscaling quality
+++++++++++++++++++++++++

The ``BICUBIC`` filter for affine transformations produced sharp, slightly
pixelated image for upscaling. Bicubic for convolutions is more soft.

Resize performance
++++++++++++++++++

In most cases, convolution is more a expensive algorithm for downscaling
because it takes into account all the pixels of source image. Therefore
``BILINEAR`` and ``BICUBIC`` filters' performance can be lower than before.
On the other hand the quality of ``BILINEAR`` and ``BICUBIC`` was close to
``NEAREST``. So if such quality is suitable for your tasks you can switch to
``NEAREST`` filter for downscaling, which will give a huge improvement in
performance.

At the same time performance of convolution resampling for downscaling has been
improved by around a factor of two compared to the previous version.
The upscaling performance of the ``LANCZOS`` filter has remained the same. For
``BILINEAR`` filter it has improved by 1.5 times and for ``BICUBIC`` by four
times.

Default filter for thumbnails
+++++++++++++++++++++++++++++

In Pillow 2.5 the default filter for :py:meth:`~PIL.Image.Image.thumbnail` was
changed from ``NEAREST`` to ``ANTIALIAS``. Antialias was chosen because all the
other filters gave poor quality for reduction. Starting from Pillow 2.7.0,
``ANTIALIAS`` has been replaced with ``BICUBIC``, because it's faster and
``ANTIALIAS`` doesn't give any advantages after downscaling with libjpeg, which
uses supersampling internally, not convolutions.

Image transposition
+++++++++++++++++++

A new method ``TRANSPOSE`` has been added for the
:py:meth:`~PIL.Image.Image.transpose` operation in addition to
``FLIP_LEFT_RIGHT``, ``FLIP_TOP_BOTTOM``, ``ROTATE_90``, ``ROTATE_180``,
``ROTATE_270``. ``TRANSPOSE`` is an algebra transpose, with an image reflected
across its main diagonal.

The speed of ``ROTATE_90``, ``ROTATE_270`` and ``TRANSPOSE`` has been significantly
improved for large images which don't fit in the processor cache.

Gaussian blur and unsharp mask
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :py:meth:`~PIL.ImageFilter.GaussianBlur` implementation has been replaced
with a sequential application of box filters. The new implementation is based on
"Theoretical foundations of Gaussian convolution by extended box filtering" from
the Mathematical Image Analysis Group. As :py:meth:`~PIL.ImageFilter.UnsharpMask`
implementations use Gaussian blur internally, all changes from this chapter
are also applicable to it.

Blur radius
+++++++++++

There was an error in the previous version of Pillow, where blur radius (the
standard deviation of Gaussian) actually meant blur diameter. For example, to
blur an image with actual radius 5 you were forced to use value 10. This has
been fixed. Now the meaning of the radius is the same as in other software.

If you used a Gaussian blur with some radius value, you need to divide this
value by two.

Blur performance
++++++++++++++++

Box filter computation time is constant relative to the radius and depends
on source image size only. Because the new Gaussian blur implementation
is based on box filter, its computation time also doesn't depend on the blur
radius.

For example, previously, if the execution time for a given test image was 1
second for radius 1, 3.6 seconds for radius 10 and 17 seconds for 50, now blur
with any radius on same image is executed for 0.2 seconds.

Blur quality
++++++++++++

The previous implementation takes into account only source pixels within
2 * standard deviation radius for every destination pixel. This was not enough,
so the quality was worse compared to other Gaussian blur software.

The new implementation does not have this drawback.

TIFF parameter changes
^^^^^^^^^^^^^^^^^^^^^^

Several kwarg parameters for saving TIFF images were previously
specified as strings with included spaces (e.g. 'x resolution'). This
was difficult to use as kwargs without constructing and passing a
dictionary. These parameters now use the underscore character instead
of space. (e.g. 'x_resolution')

---

### Releasenotes 2.8.0 (`docs/releasenotes/2.8.0.rst`)

2.8.0
-----

Open HTTP response objects with Image.open
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

HTTP response objects returned from ``urllib2.urlopen(url)`` or
``requests.get(url, stream=True).raw`` are 'file-like' but do not support ``.seek()``
operations. As a result PIL was unable to open them as images, requiring a wrap in
``cStringIO`` or ``BytesIO``.

Now new functionality has been added to ``Image.open()`` by way of an ``.seek(0)`` check and
catch on exception :py:exc:`AttributeError` or :py:exc:`io.UnsupportedOperation`. If this is caught we
attempt to wrap the object using ``io.BytesIO`` (which will only work on buffer-file-like
objects).

This allows opening of files using both ``urllib2`` and ``requests``, e.g.::

    Image.open(urllib2.urlopen(url))
    Image.open(requests.get(url, stream=True).raw)

If the response uses content-encoding (compression, either gzip or deflate) then this
will fail as both the urllib2 and requests raw file object will produce compressed data
in that case. Using Content-Encoding on images is rather non-sensical as most images are
already compressed, but it can still happen.

For requests the work-around is to set the decode_content attribute on the raw object to
True::

    response = requests.get(url, stream=True)
    response.raw.decode_content = True
    image = Image.open(response.raw)

---

### Releasenotes 3.0.0 (`docs/releasenotes/3.0.0.rst`)

3.0.0
-----

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

Several methods that have been marked as deprecated for many releases
have been removed in this release:

* ``Image.tostring()``
* ``Image.fromstring()``
* ``Image.offset()``
* ``ImageDraw.setink()``
* ``ImageDraw.setfill()``
* The ``ImageFileIO`` module
* The ``ImageFont.FreeTypeFont`` and ``ImageFont.truetype`` ``file`` keyword arg
* The ``ImagePalette`` private ``_make`` functions
* ``ImageWin.fromstring()``
* ``ImageWin.tostring()``

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

Saving multipage images
^^^^^^^^^^^^^^^^^^^^^^^

There is now support for saving multipage images in the ``GIF`` and
``PDF`` formats. To enable this functionality, pass in ``save_all=True``
as a keyword argument to the save::

    im.save('test.pdf', save_all=True)

TIFF ImageFileDirectory rewrite
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The TIFF ImageFileDirectory metadata code has been rewritten. Where
previously it returned a somewhat arbitrary set of values and tuples,
it now returns bare values where appropriate and tuples when the
metadata item is a sequence or collection.

The original metadata is still available in the TiffImage.tags, the
new values are available in the TiffImage.tags_v2 member. The old
structures will be deprecated at some point in the future.  When
saving TIFF metadata, new code should use the
TiffImagePlugin.ImageFileDirectory_v2 class.

LibJpeg and Zlib are required by default
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The external dependencies on libjpeg and zlib are now required by default.
If the headers or libraries are not found, then installation will abort
with an error. This behaviour can be disabled with the ``--disable-libjpeg``
and ``--disable-zlib`` flags.

---

### Releasenotes 3.1.0 (`docs/releasenotes/3.1.0.rst`)

3.1.0
-----

ImageDraw arc, chord and pieslice can now use floats
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There is no longer a need to ensure that the start and end arguments for ``arc``,
``chord`` and ``pieslice`` are integers.

Note that these numbers are not simply rounded internally, but are actually
utilised in the drawing process.

Consistent multiline text spacing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When using the ``ImageDraw`` multiline methods, the spacing between
lines was inconsistent, based on the combination on ascenders and
descenders.

This has now been fixed, so that lines are offset by their baselines,
not the absolute height of each line.

There is also now a default spacing of 4px between lines.

EXIF, JPEG and TIFF metadata
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There were major changes in the TIFF ImageFileDirectory support in
Pillow 3.0 that led to a number of regressions. Some of them have been
fixed in Pillow 3.1, and some of them have been extended to have
different behavior.

TiffImagePlugin.IFDRational
+++++++++++++++++++++++++++

Pillow 3.0 changed rational metadata to use a float. In Pillow 3.1,
this has changed to allow the expression of 0/0 as a valid piece of
rational metadata to reflect usage in the wild.

Rational metadata is now encapsulated in an ``IFDRational``
instance. This class extends the Rational class to allow a denominator
of 0. It compares as a float or a number, but does allow access to the
raw numerator and denominator values through attributes.

When used in a ``ImageFileDirectory_v1``, a 2 item tuple is returned
of the numerator and denominator, as was done previously.

This class should be used when adding a rational value to an
ImageFileDirectory for saving to image metadata.

JpegImagePlugin._getexif
++++++++++++++++++++++++

In Pillow 3.0, the dictionary returned from the private, experimental,
but generally widely used ``_getexif`` function changed to reflect the
ImageFileDirectory_v2 format, without a fallback to the previous format.

In Pillow 3.1, ``_getexif`` now returns a dictionary compatible with
Pillow 2.9 and earlier, built with
``ImageFileDirectory_v1`` instances. Additionally, any
single item tuples have been unwrapped and return a bare element.

The format returned by Pillow 3.0 has been abandoned. A more fully
featured interface for EXIF is anticipated in a future release.

Out of spec metadata
++++++++++++++++++++

In Pillow 3.0 and 3.1, images that contain metadata that is internally
consistent, but not in agreement with the TIFF spec, may cause an
exception when reading the metadata.  This can happen when a tag that
is specified to have a single value is stored with an array of values.

It is anticipated that this behavior will change in future releases.

---

### Releasenotes 3.1.1 (`docs/releasenotes/3.1.1.rst`)

3.1.1
-----

Security
========

:cve:`2016-0740`: Buffer overflow in ``TiffDecode.c``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 3.1.0 and earlier when linked against libtiff >= 4.0.0 on x64
may overflow a buffer when reading a specially crafted tiff file.

Specifically, libtiff >= 4.0.0 changed the return type of
``TIFFScanlineSize`` from ``int32`` to machine dependent
``int32|64``. If the scanline is sized so that it overflows an
``int32``, it may be interpreted as a negative number, which will then
pass the size check in ``TiffDecode.c`` line 236. To do this, the
logical scanline size has to be > 2gb, and for the test file, the
allocated buffer size is 64k against a roughly 4gb scan line size. Any
image data over 64k is written over the heap, causing a segfault.

This issue was found by security researcher FourOne.

:cve:`2016-0775`: Buffer overflow in ``FliDecode.c``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In all versions of Pillow, dating back at least to the last PIL 1.1.7
release, FliDecode.c has a buffer overflow error (:cve:`2016-0775`).

Around line 192:

.. code-block:: c

  case 16:
      /* COPY chunk */
      for (y = 0; y < state->ysize; y++) {
          UINT8* buf = (UINT8*) im->image[y];
          memcpy(buf+x, data, state->xsize);
          data += state->xsize;
      }
      break;


The memcpy has error where ``x`` is added to the target buffer
address. ``X`` is used in several internal temporary variable roles,
but can take a value up to the width of the image.  ``Im->image[y]``
is a set of row pointers to segments of memory that are the size of
the row.  At the max ``y``, this will write the contents of the line
off the end of the memory buffer, causing a segfault.

This issue was found by Alyssa Besseling at Atlassian.

:cve:`2016-2533`: Buffer overflow in ``PcdDecode.c``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In all versions of Pillow, dating back at least to the last PIL 1.1.7
release, ``PcdDecode.c`` has a buffer overflow error (:cve:`2016-2533`).

The ``state.buffer`` for ``PcdDecode.c`` is allocated based on a 3
bytes per pixel sizing, where ``PcdDecode.c`` wrote into the buffer
assuming 4 bytes per pixel. This writes 768 bytes beyond the end of
the buffer into other Python object storage. In some cases, this
causes a segfault, in others an internal Python malloc error.

Integer overflow in ``Resample.c``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If a large value was passed into the new size for an image, it is
possible to overflow an ``int32`` value passed into malloc.

.. code-block:: c

    kk = malloc(xsize * kmax * sizeof(float));
    ...
    xbounds = malloc(xsize * 2 * sizeof(int));

``xsize`` is trusted user input. These multiplications can overflow,
leading the ``malloc``'d buffer to be undersized. These allocations are
followed by a loop that writes out of bounds. This can lead to
corruption on the heap of the Python process with attacker controlled
float data.

This issue was found by Ned Williamson.

---

### Releasenotes 3.1.2 (`docs/releasenotes/3.1.2.rst`)

3.1.2
-----

Security
========

:cve:`2016-3076`: Buffer overflow in Jpeg2KEncode.c
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow between 2.5.0 and 3.1.1 may overflow a buffer
when writing large Jpeg2000 files, allowing for code execution or other
memory corruption.

This occurs specifically in the function ``j2k_encode_entry``, at the line:

.. code-block:: c

    state->buffer = malloc (tile_width * tile_height * components * prec / 8);


This vulnerability requires a particular value for ``height * width``
such that ``height * width * components * precision`` overflows, at
which point the malloc will be for a smaller value than expected. The
buffer that is allocated will be ``((height * width * components *
precision) mod (2^31) / 8)``, where components is 1-4 and precision is
either 8 or
16. Common values would be 4 components at precision 8 for a standard
``RGBA`` image.

The unpackers then split an image that is laid out::

    RGBARGBARGBA....

into::


    RRR.
    GGG.
    BBB.
    AAA.


If this buffer is smaller than expected, the jpeg2k unpacker functions
will write outside the allocation and onto the heap, corrupting
memory.

This issue was found by Alyssa Besseling at Atlassian.

---

### Releasenotes 3.2.0 (`docs/releasenotes/3.2.0.rst`)

3.2.0
-----

New DDS and FTEX image plugins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``DdsImagePlugin`` reading DXT1 and DXT5 encoded ``.dds`` images was
added. DXT3 images are not currently supported.

The ``FtexImagePlugin`` reads textures used for 3D objects in
Independence War 2: Edge Of Chaos. The plugin reads a single texture
per file, in the ``.ftc`` (compressed) and ``.ftu`` (uncompressed)
formats.

Updates to the GbrImagePlugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``GbrImagePlugin`` (GIMP brush format) has been updated to fix
support for version 1 files and add support for version 2 files.

Passthrough parameters for ImageDraw.text
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageDraw.multiline_text`` and ``ImageDraw.multiline_size`` take extra
spacing parameters above what are used in ``ImageDraw.text`` and
``ImageDraw.size``. These parameters can now be passed into
``ImageDraw.text`` and ``ImageDraw.size`` and they will be passed through
to the corresponding multiline functions.

ImageSequence.Iterator changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageSequence.Iterator`` is now an actual iterator implementing the
Iterator protocol.  It is also now possible to seek to the first image
of the file when using direct indexing.

---

### Releasenotes 3.3.0 (`docs/releasenotes/3.3.0.rst`)

3.3.0
-----

Libimagequant support
^^^^^^^^^^^^^^^^^^^^^

There is now support for using libimagequant as a higher quality
quantization option in ``Image.quantize()`` on Unix-like
platforms. This support requires building Pillow from source against
libimagequant. We cannot distribute binaries due to licensing
differences.


New setup.py options
^^^^^^^^^^^^^^^^^^^^

There are two new options to control the ``build_ext`` task in ``setup.py``:

* ``--debug`` dumps all of the directories and files that are
  checked when searching for libraries or headers when building the
  extensions.
* ``--disable-platform-guessing`` removes many of the directories
  that are checked for libraries and headers for build systems or
  cross compilers that specify that information in via environment
  variables.

Resizing
^^^^^^^^

Image resampling for 8-bit per channel images was rewritten using only integer
computings. This is faster on most platforms and doesn't introduce precision
errors on the wide range of scales. With other performance improvements, this
makes resampling 60% faster on average.

Color calculation for images in the ``LA`` mode on semitransparent pixels
was fixed.

Rotation
^^^^^^^^

Rotation for angles divisible by 90 degrees now always uses transposition.
This greatly improves both quality and performance in this case.
Also, the bug with wrong image size calculation when rotating by 90 degrees
was fixed.

Image metadata
^^^^^^^^^^^^^^

The return type for binary data in version 2 Exif and Tiff metadata
has been changed from a tuple of integers to bytes. This is a change
from the behavior since 3.0.0.

---

### Releasenotes 3.3.2 (`docs/releasenotes/3.3.2.rst`)

3.3.2
-----

Security
========

Integer overflow in map.c
^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow prior to 3.3.2 may experience integer overflow errors in map.c
when reading specially crafted image files. This may lead to memory
disclosure or corruption.

Specifically, when parameters from the image are passed into
``Image.core.map_buffer``, the size of the image was calculated with
``xsize`` * ``ysize`` * ``bytes_per_pixel``. This will overflow if the
result is larger than SIZE_MAX. This is possible on a 32-bit system.

Furthermore this ``size`` value was added to a potentially attacker
provided ``offset`` value and compared to the size of the buffer
without checking for overflow or negative values.

These values were then used for creating pointers, at which point
Pillow could read the memory and include it in other images. The image
was marked readonly, so Pillow would not ordinarily write to that
memory without duplicating the image first.

This issue was found by Cris Neckar at Divergent Security.

Sign extension in Storage.c
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow prior to 3.3.2 and PIL 1.1.7 (at least) do not check for
negative image sizes in ``ImagingNew`` in ``Storage.c``. A negative
image size can lead to a smaller allocation than expected, leading to
arbitrary writes.

This issue was found by Cris Neckar at Divergent Security.

---

### Releasenotes 3.4.0 (`docs/releasenotes/3.4.0.rst`)

3.4.0
-----

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

Image.core.open_ppm removed
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The nominally private/debugging function ``Image.core.open_ppm`` has
been removed. If you were using this function, please use
``Image.open`` instead.

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

Deprecation warning when saving JPEGs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

JPEG images cannot contain an alpha channel. Pillow prior to 3.4.0
silently drops the alpha channel. With this release Pillow will now
issue a :py:exc:`DeprecationWarning` when attempting to save a ``RGBA`` mode
image as a JPEG. This will become an error in Pillow 4.2.

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

New resizing filters
^^^^^^^^^^^^^^^^^^^^

Two new filters available for ``Image.resize()`` and ``Image.thumbnail()``
functions: ``BOX`` and ``HAMMING``. ``BOX`` is the high-performance filter with
two times shorter window than ``BILINEAR``. It can be used for image reduction
3 and more times and produces a sharper result than ``BILINEAR``.

``HAMMING`` filter has the same performance as ``BILINEAR`` filter while
providing the image downscaling quality comparable to ``BICUBIC``.
Both new filters don't show good quality for the image upscaling.

New DDS decoders
^^^^^^^^^^^^^^^^

Pillow can now decode DXT3 images, as well as the previously supported
DXT1 and DXT5 formats. All three formats are now decoded in C code for
better performance.

Append images to GIF
^^^^^^^^^^^^^^^^^^^^

Additional frames can now be appended when saving a GIF file, through the
``append_images`` argument. The new frames are passed in as a list of images,
which may be have multiple frames themselves.

Note that the ``append_images`` argument is only used if ``save_all`` is also
in effect, e.g.::

    im.save(out, save_all=True, append_images=[im1, im2, ...])

Save multiple frame TIFF
^^^^^^^^^^^^^^^^^^^^^^^^

Multiple frames can now be saved in a TIFF file by using the ``save_all`` option.
e.g.::

    im.save("filename.tiff", format="TIFF", save_all=True)

---

### Releasenotes 4.0.0 (`docs/releasenotes/4.0.0.rst`)

4.0.0
-----

Python 2.6 and 3.2 dropped
^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 4.0 no longer supports Python 2.6 and 3.2. We will not be
creating binaries, testing, or retaining compatibility with these
releases. This release removes some workarounds for those Python
releases, so the final working version of Pillow on 2.6 or 3.2 is 3.4.2.

Support added for Python 3.6
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 4.0 supports Python 3.6.

OleFileIO.py
^^^^^^^^^^^^

``OleFileIO.py`` has been removed as a vendored file and is now installed
from the upstream :pypi:`olefile` PyPI package. All internal dependencies are
redirected to the olefile package. Direct accesses to
``PIL.OlefileIO`` raises a deprecation warning, then patches the
upstream olefile into ``sys.modules`` in its place.

SGI image save
^^^^^^^^^^^^^^

It is now possible to save images in modes ``L``, ``RGB``, and
``RGBA`` to the uncompressed SGI image format.

Zero sized images
^^^^^^^^^^^^^^^^^

Pillow 3.4.0 removed support for creating images with (0,0) size. This
has been reenabled, restoring pre 3.4 behavior.

Internal handles_eof flag
^^^^^^^^^^^^^^^^^^^^^^^^^

The ``handles_eof flag`` for decoding images has been removed, as there
were no internal users of the flag. Anyone maintaining image decoders
outside of the Pillow source tree should consider using the cleanup
function pointers instead.

Image.core.stretch removed
^^^^^^^^^^^^^^^^^^^^^^^^^^

The stretch function on the core image object has been removed. This
used to be for enlarging the image, but has been aliased to resize
recently.

---

### Releasenotes 4.1.0 (`docs/releasenotes/4.1.0.rst`)

4.1.0
-----

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

Several deprecated items have been removed.

* Support for spaces in tiff kwargs in the parameters for 'x resolution', 'y
  resolution', 'resolution unit', and 'date time' has been
  removed. Underscores should be used instead.

* The methods ``PIL.ImageDraw.ImageDraw.setink``,
  ``PIL.ImageDraw.ImageDraw.setfill``, and
  ``PIL.ImageDraw.ImageDraw.setfont`` have been removed.


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

Closing files when opening images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The file handling when opening images has been overhauled. Previously,
Pillow would attempt to close some, but not all image formats
after loading the image data. Now, the following behavior
is specified:

* For images where an open file is passed in, it is the
  responsibility of the calling code to close the file.

* For images where Pillow opens the file and the file is known to have
  only one frame, the file is closed after loading.

* If the file has more than one frame, or if it can't be determined,
  then the file is left open to permit seeking to subsequent
  frames. It will be closed, eventually, in the ``close`` or
  ``__del__`` methods.

* If the image is memory mapped, then we can't close the mapping to
  the underlying file until we are done with the image. The mapping
  will be closed in the ``close`` or ``__del__`` method.

Changes to GIF handling when saving
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The :py:class:`PIL.GifImagePlugin` code has been refactored to fix the flow when
saving images. There are two external changes that arise from this:

* An :py:class:`PIL.ImagePalette.ImagePalette` object is now accepted
  as a specified palette argument in :py:meth:`PIL.Image.Image.save()`.

* The image to be saved is no longer modified in place by any of the
  operations of the save function. Previously it was modified when
  optimizing the image palette.

This refactor fixed some bugs with palette handling when saving
multiple frame GIFs.

New method: Image.remap_palette
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The method :py:meth:`PIL.Image.Image.remap_palette()` has been
added. This method was hoisted from the GifImagePlugin code used to
optimize the palette.

Added decoder registry and support for Python-based decoders
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There is now a decoder registry similar to the image plugin
registries. Image plugins can register a decoder, and it will be
called when the decoding is requested. This allows for the creation of
pure Python decoders. While the Python decoders will not be as fast as
their C based counterparts, they may be easier and quicker to develop
or safer to run.

Tests
^^^^^

Many tests have been added, including correctness tests for image
formats that have been previously untested.

We are now running automated tests in Docker containers against more
Linux versions than are provided on Travis CI, which is currently
Ubuntu 14.04 x64. This Pillow release is tested on 64-bit Alpine,
Arch, Ubuntu 12.04 and 16.04, and 32-bit Debian Stretch and Ubuntu
14.04. This also covers a wider range of dependency versions than are
provided on Travis natively.

---

### Releasenotes 4.1.1 (`docs/releasenotes/4.1.1.rst`)

4.1.1
-----

Fix regression with reading DPI from EXIF data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Some JPEG images don't contain DPI information in the image metadata,
but do contain it in the EXIF data. A patch was added in 4.1.0 to read
from the EXIF data, but it did not accept all possible types that
could be included there.  This fix adds the ability to read ints as
well as rational values.

Incompatibility between 3.6.0 and 3.6.1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

CPython 3.6.1 added a new symbol, PySlice_GetIndicesEx, which was not
present in 3.6.0. This had the effect of causing binaries compiled on
CPython 3.6.1 to not work on installations of C-Python 3.6.0. This fix
undefines PySlice_GetIndicesEx if it exists to restore compatibility
with both 3.6.0 and 3.6.1. See https://bugs.python.org/issue29943 for
more details.

---

### Releasenotes 4.2.0 (`docs/releasenotes/4.2.0.rst`)

4.2.0
-----

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

Several deprecated items have been removed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* The methods ``PIL.ImageWin.Dib.fromstring``,
  ``PIL.ImageWin.Dib.tostring`` and
  ``PIL.TiffImagePlugin.ImageFileDirectory_v2.as_dict`` have
  been removed.

* Before Pillow 4.2.0, attempting to save an RGBA image as JPEG would
  discard the alpha channel. From Pillow 3.4.0, a deprecation warning
  was shown. From Pillow 4.2.0, the deprecation warning is removed and
  an :py:exc:`IOError` is raised.

Removed core Image function
^^^^^^^^^^^^^^^^^^^^^^^^^^^

The unused function ``Image.core.new_array`` was removed. This is an
internal function that should not have been used by user code, but it
was accessible from the python layer.

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

Added complex text rendering
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow now supports complex text rendering for scripts requiring glyph
composition and bidirectional flow. This optional feature adds three
dependencies: harfbuzz, fribidi, and raqm. See the :doc:`install documentation
<../installation>` for further details. This feature is tested and works on
Unix and Mac, but has not yet been built on Windows platforms.

New optional parameters
^^^^^^^^^^^^^^^^^^^^^^^

* :py:meth:`PIL.ImageDraw.floodfill` has a new optional parameter:
  threshold. This specifies a tolerance for the color to replace with
  the flood fill.

* The TIFF and PDF image writers now support the ``append_images``
  optional parameter for specifying additional images to create
  multipage outputs.

New DecompressionBomb warning
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

:py:meth:`PIL.Image.Image.crop` now may raise a DecompressionBomb
warning if the crop region enlarges the image over the threshold
specified by :py:data:`PIL.Image.MAX_IMAGE_PIXELS`.

---

### Releasenotes 4.2.1 (`docs/releasenotes/4.2.1.rst`)

4.2.1
-----

There are no functional changes in this release.

Fixed Windows PyPy build
^^^^^^^^^^^^^^^^^^^^^^^^

A change in the 4.2.0 cycle broke the Windows PyPy build. This has
been fixed, and PyPy is now part of the Windows CI matrix.

---

### Releasenotes 4.3.0 (`docs/releasenotes/4.3.0.rst`)

4.3.0
-----

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

Deprecations
^^^^^^^^^^^^

Several undocumented functions in ImageOps have been deprecated:
``gaussian_blur``, ``gblur``, ``unsharp_mask``, ``usm`` and
``box_blur``. Use the equivalent operations in ``ImageFilter``
instead. These functions will be removed in a future release.

TIFF metadata changes
^^^^^^^^^^^^^^^^^^^^^

* TIFF tags with unknown type/quantity now default to being bare
  values if they are 1 element, where previously they would be a
  single element tuple. This is only with the new api, not the legacy
  api. This normalizes the handling of fields, so that the metadata
  with inferred or image specified counts are handled the same as
  metadata with count specified in the TIFF spec.
* The ``PhotoshopInfo``, ``XMP``, and ``JPEGTables`` tags now have a
  defined type (bytes) and a count of 1.
* The ``ImageJMetaDataByteCounts`` tag now has an arbitrary number of
  items, as there can be multiple items, one for UTF-8, and one for
  UTF-16.

Core Image API changes
^^^^^^^^^^^^^^^^^^^^^^

These are internal functions that should not have been used by user
code, but they were accessible from the python layer.

Debugging code within ``Image.core.grabclipboard`` was removed. It had been
marked as ``will be removed in future versions`` since PIL. When enabled, it
identified the format of the clipboard data.

The ``PIL.Image.core.copy`` and ``PIL.Image.Image.im.copy2`` methods
have been removed.

The ``PIL.Image.core.getcount`` methods have been removed, use
``PIL.Image.core.get_stats()['new_count']`` property instead.


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

Get one channel from image
^^^^^^^^^^^^^^^^^^^^^^^^^^

A new method :py:meth:`PIL.Image.Image.getchannel` has been added to
return a single channel by index or name. For example,
``image.getchannel("A")`` will return alpha channel as separate image.
``getchannel`` should work up to 6 times faster than
``image.split()[0]`` in previous Pillow versions.

Box blur
^^^^^^^^

A new filter, :py:class:`PIL.ImageFilter.BoxBlur`, has been
added. This is a filter with similar results to a Gaussian blur, but
is much faster.

Partial resampling
^^^^^^^^^^^^^^^^^^

Added new argument ``box`` for :py:meth:`PIL.Image.Image.resize`. This
argument defines a source rectangle from within the source image to be
resized.  This is very similar to the ``image.crop(box).resize(size)``
sequence except that ``box`` can be specified with subpixel accuracy.

New transpose operation
^^^^^^^^^^^^^^^^^^^^^^^

The ``Image.TRANSVERSE`` operation has been added to
:py:meth:`PIL.Image.Image.transpose`. This is equivalent to a transpose
operation about the opposite diagonal.

Multiband filters
^^^^^^^^^^^^^^^^^

There is a new :py:class:`PIL.ImageFilter.MultibandFilter` base class
for image filters that can run on all channels of an image in one
operation. The original :py:class:`PIL.ImageFilter.Filter` class
remains for image filters that can process only single band images, or
require splitting of channels prior to filtering.

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

Loading 16-bit TIFF images
^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow now can read 16-bit multichannel TIFF files including files
with alpha transparency. The image data is truncated to 8-bit
precision.

Pillow now can read 16-bit signed integer single channel TIFF
files. The image data is promoted to 32-bit for storage and
processing.

SGI images
^^^^^^^^^^

Pillow can now read and write uncompressed 16-bit multichannel SGI
images to and from RGB and RGBA formats. The image data is truncated
to 8-bit precision.

Pillow can now read RLE encoded SGI images in both 8 and 16-bit
precision.

Performance
^^^^^^^^^^^

This release contains several performance improvements:

* Many memory bandwidth-bounded operations such as crop, image allocation,
  conversion, split into bands and merging from bands are up to 2x faster.
* Upscaling of multichannel images (such as RGB) is accelerated by 5-10%
* JPEG loading is accelerated up to 15% and JPEG saving up to 20% when
  using a recent version of libjpeg-turbo.
* ``Image.transpose`` has been accelerated 15% or more by using a cache
  friendly algorithm.
* ImageFilters based on Kernel convolution are significantly faster
  due to the new :py:class:`~PIL.ImageFilter.MultibandFilter` feature.
* All memory allocation for images is now done in blocks, rather than
  falling back to an allocation for each scan line for images larger
  than the block size.

CMYK conversion
^^^^^^^^^^^^^^^

The basic CMYK->RGB conversion has been tweaked to match the formula
from Google Chrome. This produces an image that is generally lighter
than the previous formula, and more in line with what color managed
applications produce.

---

### Releasenotes 5.0.0 (`docs/releasenotes/5.0.0.rst`)

5.0.0
-----

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

Python 3.3 dropped
^^^^^^^^^^^^^^^^^^

Python 3.3 is EOL and no longer supported due to moving testing from nose,
which is deprecated, to pytest, which doesn't support Python 3.3. We will not
be creating binaries, testing, or retaining compatibility with this version.
The final version of Pillow for Python 3.3 is 4.3.0.

Decompression bombs now raise exceptions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow has previously emitted warnings for images that are
unexpectedly large and may be a denial of service. These warnings are
now upgraded to ``DecompressionBombError``\s for images that are twice
the size of images that trigger the ``DecompressionBombWarning``. The
default threshold is 128Mpx, or 0.5GB for an ``RGB`` or ``RGBA``
image. This can be disabled or changed by setting
``Image.MAX_IMAGE_PIXELS = None``.

Scripts
^^^^^^^

The scripts formerly installed by Pillow have been split into a
separate package, pillow-scripts, living at
https://github.com/python-pillow/pillow-scripts.


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

OleFileIO.py
^^^^^^^^^^^^

The :pypi:`olefile` module is no longer a required dependency when installing Pillow.
Support for plugins requiring olefile will not be loaded if it is not
installed. This allows library consumers to avoid installing this dependency
if they choose. Some library consumers have little interest in the format
support and would like to keep dependencies to a minimum.

Further, the vendored version was removed in Pillow 4.0.0 and replaced with a
deprecation warning that PIL.OleFileIO would be removed in a future version.
This warning has been upgraded to an import error pending future removal.

Check parameter on _save
^^^^^^^^^^^^^^^^^^^^^^^^

Several image plugins supported a named ``check`` parameter on their
nominally private ``_save`` method to preflight if the image could be
saved in that format. That parameter has been removed.

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

Image.transform
^^^^^^^^^^^^^^^

A new named parameter, ``fillcolor``, has been added to
``Image.transform``. This color specifies the background color to use in
the area outside the transformed area in the output image. This
parameter takes the same color specifications as used in ``Image.new``.

GIF disposal
^^^^^^^^^^^^

Multiframe GIF images now take an optional disposal parameter to
specify the disposal option for changed pixels.

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

Compressed TIFF images
^^^^^^^^^^^^^^^^^^^^^^

Previously, there were some compression modes (JPEG, Packbits, and
LZW) that were supported with Pillow's internal TIFF decoder. All
compressed TIFFs are now read using the ``libtiff`` decoder, as it
implements the compression schemes more correctly.

Libraqm is now dynamically linked
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The libraqm dependency for complex text scripts is now linked
dynamically at runtime rather than at packaging time. This allows us
to release binaries with support for libraqm if it is installed on the
user's machine.

Source layout changes
^^^^^^^^^^^^^^^^^^^^^

The Pillow source is now stored within the ``src`` directory of the
distribution. This prevents accidental imports of the PIL directory
when running Python from the project directory.

Setup.py changes
^^^^^^^^^^^^^^^^

Multiarch support on Linux should be more robust, especially on Debian
derivatives on ARM platforms. Debian's multiarch platform
configuration is run in preference to the sniffing of machine platform
and architecture.

---

### Releasenotes 5.1.0 (`docs/releasenotes/5.1.0.rst`)

5.1.0
-----

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

Optional channels for TIFF files
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow can now open TIFF files with base modes of ``RGB``, ``YCbCr``,
and ``CMYK`` with up to 6 8-bit channels, discarding any extra
channels if the content is tagged as UNSPECIFIED.  Pillow still does
not store more than 4 8-bit channels of image data.

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

Append to PDF files
^^^^^^^^^^^^^^^^^^^

Images can now be appended to PDF files in place by passing in
``append=True`` when saving the image.

New BLP file format
^^^^^^^^^^^^^^^^^^^

Pillow now supports reading the BLP "Blizzard Mipmap" file format used
for tiles in Blizzard's engine.

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

WebP memory leak
^^^^^^^^^^^^^^^^

A memory leak when opening ``WebP`` files has been fixed.

---

### Releasenotes 5.2.0 (`docs/releasenotes/5.2.0.rst`)

5.2.0
-----

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

Deprecations
^^^^^^^^^^^^

These version constants have been deprecated. ``VERSION`` will be removed in
Pillow 6.0.0, and ``PILLOW_VERSION`` will be removed after that.

* ``PIL.VERSION`` (old PIL version 1.1.7)
* ``PIL.PILLOW_VERSION``
* ``PIL.Image.VERSION``
* ``PIL.Image.PILLOW_VERSION``

Use ``PIL.__version__`` instead.

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

3D color lookup tables
^^^^^^^^^^^^^^^^^^^^^^

Support for 3D color lookup table transformations has been added.

* https://en.wikipedia.org/wiki/3D_lookup_table

``Color3DLUT.generate`` transforms 3-channel pixels using the values of the
channels as coordinates in the 3D lookup table and interpolating the nearest
elements.

It allows you to apply almost any color transformation in constant time by
using pre-calculated decimated tables.

``Color3DLUT.transform()`` allows altering table values with a callback.

If NumPy is installed, the performance of argument conversion is dramatically
improved when a source table supports buffer interface (NumPy && arrays in
Python >= 3).

ImageColor.getrgb
^^^^^^^^^^^^^^^^^

Previously ``Image.rotate`` only supported HSL color strings. Now HSB and HSV
strings are also supported, as well as float values. For example,
``ImageColor.getrgb("hsv(180,100%,99.5%)")``.

ImageFile.get_format_mimetype
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageFile.get_format_mimetype`` has been added to return the MIME type of an
image file, where available. For example,
``Image.open("hopper.jpg").get_format_mimetype()`` returns ``"image/jpeg"``.

ImageFont.getsize_multiline
^^^^^^^^^^^^^^^^^^^^^^^^^^^

A new method to return the size of multiline text, for example
``font.getsize_multiline("ABC\nAaaa")``

Image.rotate
^^^^^^^^^^^^

A new named parameter, ``fillcolor``, has been added to ``Image.rotate``. This
color specifies the background color to use in the area outside the rotated
image. This parameter takes the same color specifications as used in
``Image.new``.


TGA file format
^^^^^^^^^^^^^^^

Pillow can now read and write LA data (in addition to L, P, RGB and RGBA), and
write RLE data (in addition to uncompressed).

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

Support added for Python 3.7
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pillow 5.2 supports Python 3.7.

Build macOS wheels with Xcode 6.4, supporting older macOS versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The macOS wheels for Pillow 5.1.0 were built with Xcode 9.2, meaning 10.12
Sierra was the lowest supported version.

Prior to Pillow 5.1.0, Xcode 8 was used, supporting El Capitan 10.11.

Instead, Pillow 5.2.0 is built with the oldest available Xcode 6.4 to support
at least 10.10 Yosemite.

Fix _i2f compilation with some GCC versions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For example, this allows compilation with GCC 4.8 on NetBSD.

Resolve confusion getting PIL / Pillow version string
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Re: "version constants deprecated" listed above, as user gnbl notes in #3082:

- it's confusing that PIL.VERSION returns the version string of the former PIL instead of Pillow's
- ReadTheDocs documentation is missing for some version branches (why is this, will it ever change, ...)
- it's confusing that PIL.version is a module and does not return the version information directly or hints on how to get it
- the package information header is essentially useless (placeholder, does not even mention Pillow, nor the version)
- PIL._version module documentation comment could explain how to access the version information

We have attempted to resolve these issues in #3083, #3090 and #3218.

---

### Releasenotes 5.3.0 (`docs/releasenotes/5.3.0.rst`)

5.3.0
-----

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

Image size
^^^^^^^^^^

If you attempt to set the size of an image directly, e.g.
``im.size = (100, 100)``, you will now receive an :py:exc:`AttributeError`. This is
not about removing existing functionality, but instead about raising an
explicit error to prevent later consequences. The ``resize`` method is the
correct way to change an image's size.

The exceptions to this are:

* The ICO and ICNS image formats, which use ``im.size = (100, 100)`` to select a subimage.
* The TIFF image format, which now has a :py:exc:`DeprecationWarning` for this action,
  as direct image size setting was previously necessary to work around an issue with tile extents.


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

Added line width parameter to rectangle and ellipse-based shapes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

An optional line ``width`` parameter has been added to ``ImageDraw.Draw.arc``,
``chord``, ``ellipse``, ``pieslice`` and ``rectangle``.

Curved joints for line sequences
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``ImageDraw.Draw.line`` draws a line, or lines, between points. Previously,
when multiple points are given, for a larger ``width``, the joints between
these lines looked unsightly. There is now an additional optional argument,
``joint``, defaulting to :data:`None`. When it is set to ``curved``, the joints
between the lines will become rounded.

ImageOps.colorize
^^^^^^^^^^^^^^^^^

Previously ``ImageOps.colorize`` only supported two-color mapping with
``black`` and ``white`` arguments being mapped to 0 and 255 respectively.
Now it supports three-color mapping with the optional ``mid`` parameter, and
the positions for all three color arguments can each be optionally specified
(``blackpoint``, ``whitepoint`` and ``midpoint``).
For example, with all optional arguments::

    ImageOps.colorize(im, black=(32, 37, 79), white='white', mid=(59, 101, 175),
                          blackpoint=15, whitepoint=240, midpoint=100)

ImageOps.pad
^^^^^^^^^^^^

While ``ImageOps.fit`` allows users to crop images to a requested aspect ratio
and size, new method ``ImageOps.pad`` pads images to fill a requested aspect
ratio and size, filling new space with a provided ``color`` and positioning the
image within the new area through a ``centering`` argument.

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

Added support for reading tiled TIFF images through LibTIFF. Compressed TIFF
images are now read through LibTIFF.

RGB WebP images are now read as RGB mode, rather than RGBX.

---

--- METRICS ---
- Files Extracted: 101
- Estimated Token Budget: ~126366 tokens
- Canonical Reference: https://codewiki.google/github.com/python-pillow/Pillow
