Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refer to Resampling enum #6868

Merged
merged 2 commits into from
Jan 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions docs/handbook/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,44 +148,44 @@ pixel, the Python Imaging Library provides different resampling *filters*.

.. py:currentmodule:: PIL.Image

.. data:: NEAREST
.. data:: Resampling.NEAREST

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

.. data:: BOX
.. data:: Resampling.BOX

Each pixel of source image contributes to one pixel of the
destination image with identical weights.
For upscaling is equivalent of :data:`NEAREST`.
For upscaling is equivalent of :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:: BILINEAR
.. data:: Resampling.BILINEAR

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:: HAMMING
.. data:: Resampling.HAMMING

Produces a sharper image than :data:`BILINEAR`, doesn't have dislocations
on local level like with :data:`BOX`.
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:: BICUBIC
.. data:: Resampling.BICUBIC

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:: LANCZOS
.. data:: Resampling.LANCZOS

Calculate the output pixel value using a high-quality Lanczos filter (a
truncated sinc) on all pixels that may contribute to the output value.
Expand All @@ -198,19 +198,19 @@ pixel, the Python Imaging Library provides different resampling *filters*.
Filters comparison table
~~~~~~~~~~~~~~~~~~~~~~~~

+----------------+-------------+-----------+-------------+
| Filter | Downscaling | Upscaling | Performance |
| | quality | quality | |
+================+=============+===========+=============+
|:data:`NEAREST` | | | ⭐⭐⭐⭐⭐ |
+----------------+-------------+-----------+-------------+
|:data:`BOX` | ⭐ | | ⭐⭐⭐⭐ |
+----------------+-------------+-----------+-------------+
|:data:`BILINEAR`| ⭐ | ⭐ | ⭐⭐⭐ |
+----------------+-------------+-----------+-------------+
|:data:`HAMMING` | ⭐⭐ | | ⭐⭐⭐ |
+----------------+-------------+-----------+-------------+
|:data:`BICUBIC` | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
+----------------+-------------+-----------+-------------+
|:data:`LANCZOS` | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
+----------------+-------------+-----------+-------------+
+---------------------------+-------------+-----------+-------------+
| Filter | Downscaling | Upscaling | Performance |
| | quality | quality | |
+===========================+=============+===========+=============+
|:data:`Resampling.NEAREST` | | | ⭐⭐⭐⭐⭐ |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BOX` | ⭐ | | ⭐⭐⭐⭐ |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BILINEAR`| ⭐ | ⭐ | ⭐⭐⭐ |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.HAMMING` | ⭐⭐ | | ⭐⭐⭐ |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.BICUBIC` | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
+---------------------------+-------------+-----------+-------------+
|:data:`Resampling.LANCZOS` | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
+---------------------------+-------------+-----------+-------------+
1 change: 1 addition & 0 deletions docs/reference/Image.rst
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ See :ref:`concept-filters` for details.
.. autoclass:: Resampling
:members:
:undoc-members:
:noindex:

Some deprecated filters are also available under the following names:

Expand Down
76 changes: 35 additions & 41 deletions docs/releasenotes/2.7.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,84 +29,78 @@ 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:
:py:data:`PIL.Image.NEAREST`, :py:data:`PIL.Image.BILINEAR`,
:py:data:`PIL.Image.BICUBIC` and :py:data:`PIL.Image.ANTIALIAS`.
Almost all of them were changed in this version.
``NEAREST``, ``BILINEAR``, ``BICUBIC`` and ``ANTIALIAS``. Almost all of them
were changed in this version.

Bicubic and bilinear downscaling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

From the beginning :py:data:`~PIL.Image.BILINEAR` and
:py:data:`~PIL.Image.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 :py:data:`~PIL.Image.BILINEAR` and 4x4 for
:py:data:`~PIL.Image.BICUBIC`). This gave an unsatisfactory result for
downscaling. At the same time, a high quality convolutions-based algorithm with
flexible kernel was used for :py:data:`~PIL.Image.ANTIALIAS` filter.
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
:py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` filters
(for example, reducing within several steps), they are unnecessary now.
``BILINEAR`` and ``BICUBIC`` filters (for example, reducing within several
steps), they are unnecessary now.

Antialias renamed to Lanczos
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A new :py:data:`PIL.Image.LANCZOS` constant was added instead of
:py:data:`~PIL.Image.ANTIALIAS`.
A new ``LANCZOS`` constant was added instead of ``ANTIALIAS``.

When :py:data:`~PIL.Image.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
:py:data:`~PIL.Image.ANTIALIAS` filter is Lanczos filter.
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 :py:data:`~PIL.Image.ANTIALIAS` constant is left for backward compatibility
and is an alias for :py:data:`~PIL.Image.LANCZOS`.
The ``ANTIALIAS`` constant is left for backward compatibility and is an alias
for ``LANCZOS``.

Lanczos upscaling quality
^^^^^^^^^^^^^^^^^^^^^^^^^

The image upscaling quality with :py:data:`~PIL.Image.LANCZOS` filter was
almost the same as :py:data:`~PIL.Image.BILINEAR` due to bug. This has been fixed.
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 :py:data:`~PIL.Image.BICUBIC` filter for affine transformations produced
sharp, slightly pixelated image for upscaling. Bicubic for convolutions is
more soft.
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
:py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` filters'
performance can be lower than before. On the other hand the quality of
:py:data:`~PIL.Image.BILINEAR` and :py:data:`~PIL.Image.BICUBIC` was close to
:py:data:`~PIL.Image.NEAREST`. So if such quality is suitable for your tasks
you can switch to :py:data:`~PIL.Image.NEAREST` filter for downscaling,
which will give a huge improvement in performance.
``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 :py:data:`~PIL.Image.LANCZOS` filter has
remained the same. For :py:data:`~PIL.Image.BILINEAR` filter it has improved by
1.5 times and for :py:data:`~PIL.Image.BICUBIC` by four times.
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 :py:data:`~PIL.Image.NEAREST` to :py:data:`~PIL.Image.ANTIALIAS`.
Antialias was chosen because all the other filters gave poor quality for
reduction. Starting from Pillow 2.7.0, :py:data:`~PIL.Image.ANTIALIAS` has been
replaced with :py:data:`~PIL.Image.BICUBIC`, because it's faster and
:py:data:`~PIL.Image.ANTIALIAS` doesn't give any advantages after
downscaling with libjpeg, which uses supersampling internally, not convolutions.
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
-------------------
Expand Down
12 changes: 8 additions & 4 deletions src/PIL/ImageOps.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ def contain(image, size, method=Image.Resampling.BICUBIC):
:param size: The requested output size in pixels, given as a
(width, height) tuple.
:param method: Resampling method to use. Default is
:py:attr:`PIL.Image.BICUBIC`. See :ref:`concept-filters`.
:py:attr:`PIL.Image.Resampling.BICUBIC`.
radarhere marked this conversation as resolved.
Show resolved Hide resolved
See :ref:`concept-filters`.
:return: An image.
"""

Expand Down Expand Up @@ -276,7 +277,8 @@ def pad(image, size, method=Image.Resampling.BICUBIC, color=None, centering=(0.5
:param size: The requested output size in pixels, given as a
(width, height) tuple.
:param method: Resampling method to use. Default is
:py:attr:`PIL.Image.BICUBIC`. See :ref:`concept-filters`.
:py:attr:`PIL.Image.Resampling.BICUBIC`.
radarhere marked this conversation as resolved.
Show resolved Hide resolved
See :ref:`concept-filters`.
:param color: The background color of the padded image.
:param centering: Control the position of the original image within the
padded version.
Expand Down Expand Up @@ -328,7 +330,8 @@ def scale(image, factor, resample=Image.Resampling.BICUBIC):
:param image: The image to rescale.
:param factor: The expansion factor, as a float.
:param resample: Resampling method to use. Default is
:py:attr:`PIL.Image.BICUBIC`. See :ref:`concept-filters`.
:py:attr:`PIL.Image.Resampling.BICUBIC`.
radarhere marked this conversation as resolved.
Show resolved Hide resolved
See :ref:`concept-filters`.
:returns: An :py:class:`~PIL.Image.Image` object.
"""
if factor == 1:
Expand Down Expand Up @@ -425,7 +428,8 @@ def fit(image, size, method=Image.Resampling.BICUBIC, bleed=0.0, centering=(0.5,
:param size: The requested output size in pixels, given as a
(width, height) tuple.
:param method: Resampling method to use. Default is
:py:attr:`PIL.Image.BICUBIC`. See :ref:`concept-filters`.
:py:attr:`PIL.Image.Resampling.BICUBIC`.
radarhere marked this conversation as resolved.
Show resolved Hide resolved
See :ref:`concept-filters`.
:param bleed: Remove a border around the outside of the image from all
four edges. The value is a decimal percentage (use 0.01 for
one percent). The default value is 0 (no border).
Expand Down