7.0.0

Backwards Incompatible Changes

Python 2.7

Pillow has dropped support for Python 2.7, which reached end-of-life on 2020-01-01.

PILLOW_VERSION constant

PILLOWVERSION has been removed. Use _version instead.

PIL.*ImagePlugin.version attributes

The version constants of individual plugins have been removed. Use PIL.versioninstead.

RemovedRemovedRemoved
BmpImagePlugin.versionJpeg2KImagePlugin.versionPngImagePlugin.version
CurImagePlugin.versionJpegImagePlugin.versionPpmImagePlugin.version
DcxImagePlugin.versionMcIdasImagePlugin.versionPsdImagePlugin.version
EpsImagePlugin.versionMicImagePlugin.versionSgiImagePlugin.version
FliImagePlugin.versionMpegImagePlugin.versionSunImagePlugin.version
FpxImagePlugin.versionMpoImagePlugin.versionTgaImagePlugin.version
GdImageFile.versionMspImagePlugin.versionTiffImagePlugin.version
GifImagePlugin.versionPalmImagePlugin.versionWmfImagePlugin.version
IcoImagePlugin.versionPcdImagePlugin.versionXbmImagePlugin.version
ImImagePlugin.versionPcxImagePlugin.versionXpmImagePlugin.version
ImtImagePlugin.versionPdfImagePlugin.versionXVThumbImagePlugin.version
IptcImagePlugin.versionPixarImagePlugin.version

PyQt4 and PySide

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

Support for PyQt4 and PySide has been removed from ImageQt. Please upgrade to PyQt5or PySide2.

Setting the size of TIFF images

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

Default resampling filter

The default resampling filter has been changed to the high-quality convolutionImage.BICUBIC instead of Image.NEAREST, for the resize()method and the pad(), scale()and fit() functions.Image.NEAREST is still always used for images in “P” and “1” modes.See Filters to learn the difference. In short,Image.NEAREST is a very fast filter, but simple and low-quality.

Image.draft() return value

If the draft() method has no effect, it returns None.If it does have an effect, then it previously returned the image itself.However, unlike other chain methods, draft() does notreturn a modified version of the image, but modifies it in-place. So instead, ifdraft() has an effect, Pillow will now return a tupleof the image mode and a co-ordinate box. The box is the original coordinates in thebounds of resulting image. This may be useful in a subsequentresize() call.

API Additions

Custom unidentified image error

Pillow will now throw a custom UnidentifiedImageError when an image cannot beidentified. For backwards compatibility, this will inherit from IOError.

New argument reducing_gap for Image.resize() and Image.thumbnail() methods

Speeds up resizing by resizing the image in two steps. The bigger reducing_gap,the closer the result to the fair resampling. The smaller reducing_gap,the faster resizing. With reducing_gap greater or equal to 3.0,the result is indistinguishable from fair resampling.

The default value for resize() is None,which means that the optimization is turned off by default.

The default value for thumbnail() is 2.0,which is very close to fair resampling while still being faster in many cases.In addition, the same gap is applied when thumbnail()calls draft(), which may greatly improve the qualityof JPEG thumbnails. As a result, thumbnail()in the new version provides equally high speed and high quality from anysource (JPEG or arbitrary images).

New Image.reduce() method

reduce() is a highly efficient operationto reduce an image by integer times. Normally, it shouldn’t be used directly.Used internally by resize() and thumbnail()methods to speed up resize when a new argument reducing_gap is set.

Loading WMF images at a given DPI

On Windows, Pillow can read WMF files, with a default DPI of 72. An image cannow also be loaded at another resolution:

  1. from PIL import Image
  2. with Image.open("drawing.wmf") as im:
  3. im.load(dpi=144)

Other Changes

Image.del

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

Previous method:

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

Use instead:

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

Better thumbnail geometry

When calculating the new dimensions in thumbnail(),round to the nearest integer, instead of always rounding down.This better preserves the original aspect ratio.

When the image width or height is not divisible by 8 the last row and columnin the image get the correct weight after JPEG DCT scaling.