https://pillow.readthedocs.io/en/stable/releasenotes/13.0.0.html
Removals
Deprecations
- Deprecate IM image format #9849 [@radarhere]
- Deprecate ImageQt align8to32() in favour of raw encoder stride #9940 [@akx]
- Deprecate JpegImageFile.load_djpeg #9924 [@akx]
Documentation
Dependencies
Testing
Type hints
Other changes
- Validate TIFF tag values against libtiff's own field definition before TIFFSetField #10227 [@hugovk]
- Take libtiff scanline geometry tags from the image, not tiffinfo/exif #10226 [@hugovk]
- Bound retained TIFF tag data by stream size #10225 [@hugovk]
- Fix heap buffer overflow in _tiffWriteProc when saving TIFF to BytesIO #10224 [@hugovk]
- Use bit plane row size for P;2L and P;4L rawmodes #10186 [@aclark4life]
- Allow floating point constants in ImageMath operations #10218 [@vera-rubin]
- Correct reusing a palette entry #10084 [@sergioperezcheco]
- Add support for ImageOps invert, posterize and solarize of P images #10174 [@RavSinghChandan]
- Respect explicit BASIC layout in font_variant() #10214 [@iAlturki]
- Improve support for TGA images in P mode with an RGBA palette #10211 [@sungbin1015]
- Do not lazily import olefile #10213 [@radarhere]
- Keep the first of duplicate TIFF tags #10210 [@radarhere]
- Use reducing_gap when resizing RGBA and LA images #10208 [@antonsoo]
- Use pen widths when drawing ImageDraw2 shape outlines #10207 [@xiehuanyi]
- Run garbage collection after closing memoryview on PyPy #10203 [@radarhere]
- Reject TIFFs whose unpacker row is wider than libtiff's decoded row #10201 [@aclark4life]
- Write all channels when saving a one pixel wide RGB image as PCX #10113 [@SulimanAbdulrazzaq]
- Fix drawing on I;16B images #9982 [@akx]
- Free Threading fixes #10196 [@wiredfool]
- Correct directory name in depends/install_openjpeg.sh #10199 [@radarhere]
- Allow ImageOps to create zero dimension images #9673 [@radarhere]
- Clarify license of vendored FriBiDi shim #10194 [@aclark4life]
- Ignore (0, 0) BMP DPI #10187 [@radarhere]
- Do not write IFD1 as a tag when converting EXIF to bytes #10188 [@sungbin1015]
- Reject exporting Arrow arrays from non-contiguous images #10172 [@wiredfool]
- Check WebP canvas size before creating decoder #10190 [@radarhere]
- Apply "bits" to saving L mode PNG images #10168 [@radarhere]
- Walk PDF page tree iteratively #10185 [@aclark4life]
- Allow C comments in XBM headers #10164 [@aclark4life]
- Clear TIFF strip and tile buffer beyond previously decoded data #10184 [@aclark4life]
- Fix KeyError on missing Interop or MakerNote IFD #10177 [@RavSinghChandan]
- Fix ColorMap length when saving TIFF images with libtiff #10178 [@MohammediYunus]
- Raise ValueError for posterize bits outside 1-8 #10173 [@RavSinghChandan]
- Correct "Raw profile type exif" info after exif_transpose() #10145 [@sungbin1015]
- Raise OSError for truncated or corrupt gzip FITS data #10146 [@RavSinghChandan]
- Improve mmap buffer length check #10147 [@aryangorde6]
- Speed up ImageChops.difference() #10154 [@SimBuddy]
- Handle unexpected EOF in JPEG header #10150 [@Kesavamoorthig06]
- Correct applying OpenJPEG patch #10171 [@radarhere]
- Read from tall PSD tiles safely #10151 [@Kesavamoorthig06]
- Raise error when opening if JP2 mode is unrecognized #10135 [@radarhere]
- Add Apache-2.0 license header to Arrow.h #10162 [@aclark4life]
- Raise ValueError for XPM pixel data with undefined color key #10149 [@Kesavamoorthig06]
- Fix FLI palette OverflowError #10148 [@Kesavamoorthig06]
- Replace rgba2rgb convert function with identical rgb2rgba #10169 [@radarhere]
- Avoid copying zero-sized image buffers #10158 [@SimBuddy]
- Speed up histograms #10161 [@SimBuddy]
- Apply uclouvain/openjpeg#1621 to address OSV-2025-219 #10156 [@radarhere]
- Mark Python palette as dirty after conversion to WEB palette #10008 [@radarhere]
- Only load new palette in putpalette() if it contains raw data #10035 [@radarhere]
- Only combine PNG frames if the combined duration is still writable #10070 [@radarhere]
- Support greyscale TIFFs with ExtraSamples 0 or 1 #10140 [@officialpm]
- Avoid repeated concatenation of GIF comments #10143 [@radarhere]
- Do not change MicImageFile _n_frames or is_animated in TiffImageFile #10142 [@radarhere]
- Require TIFF ColorMap length according to BitsPerSample #10136 [@radarhere]
- Assign next PDF object ID in constant time #10133 [@radarhere]
- Reject JPEG streams whose scanlines are wider or have more components #10131 [@radarhere]
- XMP info will no longer be a tuple #10077 [@radarhere]
- Return zero from ImagePath compact() if there are no points to remove #10126 [@radarhere]
- Handle zero dimension images in RankFilter and related filters #10130 [@radarhere]
- Raise an error when calling quantize() with an empty palette #10129 [@radarhere]
- [pre-commit.ci] pre-commit autoupdate #10128 [@pre-commit-ci[bot]]
- Set PdfParser default max_nesting limit to 900 #10127 [@radarhere]
- Basic support for TSAN Docker builds #10115 [@wiredfool]
- Prevent infinite loop when rewriting PDF pages #10125 [@radarhere]
- Check COM marker length when encoding JPEG #10124 [@radarhere]
- Delay creating APNG disposal frame until necessary #10123 [@radarhere]
- Fix combining GIF frames when an earlier duration is missing #10119 [@FanWu-ai]
- Limit WMF dimensions when loading to 0-65535 #10120 [@radarhere]
- Fix use-after-free when a libtiff encode error occurs #10117 [@radarhere]
- Do not keep size from failed GIF decompression bomb check #10116 [@radarhere]
- Correct writing buffer to file in PyEncoder encode_to_file() #10098 [@radarhere]
- Improve freeing objects on errors in PyImaging_GrabScreenWin32() #10094 [@radarhere]
- Do not allow Ghostscript to render beyond decompression bomb limit #10112 [@radarhere]
- Read XBM header line by line, instead of through regex #10109 [@radarhere]
- Clear core image if mode or size has changed during seek() #10105 [@radarhere]
- Do not use deprecated getdata #9986 [@radarhere]
- Remove unused cleanup return value #10101 [@radarhere]
- Raise OSError when TIFF tile size is unexpected #10100 [@radarhere]
- Use set, rather than sorting list #10099 [@radarhere]
- Fix PSD layer tiles reading from the wrong file offset #10089 [@Arthur031221]
- Avoid unused object ids when saving PDF #10091 [@Rodrigo-Palma]
- Raise an error if PDF page loop exists #10093 [@radarhere]
- Return 0 or -1 from ImagingTransform() #10075 [@radarhere]
- Transform EPS file name to an absolute path before invoking Ghostscript #10090 [@radarhere]
- Fixed passing zero dimension images into fromarrow() #10086 [@akx]
- Add decompression bomb check to grabclipboard() on Windows #10078 [@radarhere]
- Add decompression bomb check after SPIDER seek #10076 [@radarhere]
- Speed up and simplify GIF optimization #10074 [@akx]
- Only replace a maximum of two Exif headers #10073 [@radarhere]
- Use -O2 when building wheels for macOS and Linux #10060 [@radarhere]
- Simplify code by removing instance variables #10058 [@radarhere]
- Add pathlib support for font handling #10053 [@hugovk]
- Clean up encoders deterministically on success and failure #10043 [@danking]
- When saving an ICO frame without a matching size, use the next smallest provided image #10051 [@Rodrigo-Palma]
- Remove conditionally-compiled or unreachable debug C code #9915 [@akx]
- Fix OOB read in C getlist() and _putdata() when len overstates length #9893 [@lazerg]
- When shrinking in ImageText wrap(), wrap text even if no scaling is required #10025 [@radarhere]
- Restrict ImageWin Dib paste box to bitmap #10040 [@radarhere]
- extra does not require a spare byte #10046 [@radarhere]
- Use borrowed data when exporting an image created by Image.fromarrow #9897 [@lazerg]
- Avoid overflow when multiplying integers in RankFilter #10038 [@radarhere]
- Do not pad PNG palette when saving if bits is specified #10029 [@aclark4life]
- Simplify code #10031 [@radarhere]
- Do not treat RGB as a rawmode for an RGB palette #10002 [@radarhere]
- Rearrange ImagingPoint code #10026 [@radarhere]
- Use while loop in read_prev_trailer() to avoid RecursionError #10023 [@radarhere]
- Allow zero-length members in tar files #10014 [@hugovk]
- Raise ValueError if merging image32 images #10022 [@radarhere]
- Correctly manage glyph when rendering font #10020 [@radarhere]
- Return early when applying ImageMorph MorphOp to an empty image #10021 [@radarhere]
- Do not decode more MSP data than necessary #10019 [@radarhere]
- Use int64_t for y offset #10017 [@radarhere]
- Do not decode more BMP data than necessary #10015 [@radarhere]
- Raise error when creating ImagePalette with unsupported mode #10013 [@radarhere]
- Apply hoist optimizations to Geometry.c's transforms #9788 [@akx]
- Allow for IFDRational with negative numerator and zero denominator #8970 [@radarhere]
- Offset to next TAR block must be positive #10012 [@radarhere]
- Add decompression bomb checks after seek opens new format #10011 [@radarhere]
- Raise OverflowError if text width goes below INT_MIN #10010 [@radarhere]
- Cast before multiplying #10009 [@radarhere]
- Simplify palette code #10003 [@radarhere]
- Optimize histogram generation + fix masked histograms for 2-band images + add test coverage #10005 [@akx]
- Add escape argument to PSDraw text method #9996 [@lllleolin-max]
- Link FreeType against the bundled HarfBuzz in wheels #9913 [@akx]
- Speed up some conversions #9807 [@akx]
- Speed up
Image.getbbox(); fix it for I;16 modes #9768 [@akx]
- Apply restrict optimizations to ImagingQuantize's output loop #10006 [@akx]
- Speed up
getpixel() and get_flattened_data() #9881 [@akx]
- Mark ImageFile._open() as abstract #9876 [@radarhere]
- Return 0 or -1 from ImagingSplit(), rather than number of bands #9988 [@radarhere]
- If height is scaled down significantly more than width, resize vertically first #9549 [@radarhere]
- Compile less libtiff bits for wheels #9970 [@akx]
- Preserve transparency when padding and expanding images #9995 [@lllleolin-max]
- Move kernel size check into getlist() #9987 [@radarhere]
PIL._binary: Use int.to_bytes() for faster conversion #9981 [@akx]
- Prevent negative ImageStat variance #9994 [@lllleolin-max]
- Restore image position after an error in ImageSequence.all_frames() #9999 [@niukanen1]
- Return palette contents in suitable format for C putpalette() #9985 [@radarhere]
- Parenthesize
MIN/MAX macro arguments #9928 [@akx]
- Add decompression bomb check when loading WmfStubImageFile at a different DPI #9984 [@radarhere]
- Reject invalid radius in BoxBlur and GaussianBlur #9983 [@radarhere]
- Fix ImageChops.offset for 16-bit modes + speed up #9975 [@akx]
- Speed up
Image.filter() for I;16* #9760 [@akx]
- Fix cross-compiling by searching the right lib and include directories #7634 [@chewi]
- Speed up
Image.offset #9753 [@akx]
- Remove duration and timestamp from AVIF info after seek #9973 [@dylanpulver]
- Use lazy imports on Python 3.15 to improve startup speed #9733 [@hugovk]
- [pre-commit.ci] pre-commit autoupdate #9969 [@pre-commit-ci[bot]]
- Remove duration and timestamp from WebP info after seek #9791 [@radarhere]
- If ICO image is smaller than (16, 16), save original size by default #9766 [@radarhere]
- If reducing by a factor of 1, crop #9959 [@radarhere]
- Inspect arg as Python object, instead of using PyErr_Clear() #9726 [@radarhere]
- Copy palette when transforming PA images #9965 [@radarhere]
- Treat FITS data as big-endian #9575 [@radarhere]
- Correct error message for matrix length #9956 [@radarhere]
- Copy qtables list when saving JPEG image #9919 [@lazerg]
- Avoid integer overflow when calculating reduced image size #9904 [@lazerg]
- Copy list-valued info entries independently in Image.copy() #9964 [@lazerg]
- Avoid blocking all threads when decoding AVIF image #9930 [@WillyJL]
- Use a critical section to protect getlist() #9853 [@lazerg]
- Add GPSHPositioningError to GPS IFD tag data #9941 [@dylanpulver]
- Use bytearray instead of BytesIO in MspDecoder #9877 [@radarhere]
- Reject non-finite radius in BoxBlur #9906 [@JonnasFigueiredo]
- Raise ValueError for truncated tRNS PNG chunks #9934 [@VenishPaneliya]
- Adjust tuple construction in ImageGrab to fix mypy on macOS #9935 [@akx]
- Add support for Magic Kernel Sharp resizing modes #8811 [@drhead]
- Remove depends/install_raqm_cmake.sh; update FreeBSD instructions #9927 [@akx]
- Fix comparison off-by-one in
getModeData/getRawModeData #9932 [@akx]
- Fix convert() from I;16N to I or F clipping 16-bit values #9931 [@Kayvan-Zahiri]
- Mark StubHandler.open() as abstract #9872 [@radarhere]
- Add strip_namespaces argument to Image.getxmp() #9882 [@geeno16]
- Add _normalize_coords() to reduce duplicate code #9899 [@radarhere]
- Rename IMAGING_TYPE_SPECIAL to IMAGING_TYPE_I16 #9794 [@radarhere]
- Remove unnecessary check #9874 [@radarhere]
- Improve reference handling in encode.c #9920 [@radarhere]
- PySequence_Fast raises its own TypeError #9921 [@radarhere]
- Import external headers with angle brackets #9912 [@radarhere]
- Remove unused ImagingConvertInPlace #9878 [@radarhere]
- Use GitHub's automerge instead of Mergify #9126 [@hugovk]
- Rename C convert2 to convert_into #9911 [@radarhere]
- PDF dictionary key must be a name #9884 [@radarhere]
- Remove unused C convert method #9910 [@radarhere]
- Do not open YCbCr colorspace images as RGB without libtiff #9779 [@radarhere]
- Fix loading XPM images with transparency #9848 [@nyxst4ck]
- Open BMP image with black palette in mode 1 #9778 [@radarhere]
- Remove palette if no longer relevant after TIFF seek #9855 [@radarhere]
- Add
mixed-line-ending to prek and convert to LF #9886 [@hugovk]
- Correct CmsProfile creation_date month #9804 [@radarhere]
- Raise ValueError for truncated gAMA and cHRM PNG chunks #9880 [@VenishPaneliya]
- Use PyErr_Format instead of sprintf #9863 [@akx]
- Remove unneeded code for handling zero-width characters #9875 [@radarhere]
- Simplify code to improve performance #9860 [@hugovk]
- Move ImageCmsTransform mode check into C #9793 [@radarhere]
- Save as RGB(A) when APNG frames have different palettes #9870 [@DSeaStar]
- Simplified SPIDER code #9823 [@radarhere]
- Use
fmt: skip instead of fmt: off/fmt: on #9828 [@akx]
- Reorder ImageMode tuples #9808 [@radarhere]
- Handle zero dimensions in ImagingOffset #9847 [@Mengxi-Xu]
- [pre-commit.ci] pre-commit autoupdate #9843 [@pre-commit-ci[bot]]
- Derive PCX band count from the image, not the line width #9798 [@chuenchen309]
- Fix BMP save of a P image with an empty palette #9746 [@binggao1230]
- Do not read any further than necessary when decoding BMP images with RLE8 compression #9824 [@radarhere]
- Fix unexpected errors when decoding truncated QOI images #9813 [@abhi-0203]
- Raise ValueError instead of asserting ImageOps colorize() arguments #9825 [@LuShadowX]
- Fix retrieving ImagePalette colors from raw palettes #9821 [@nightcityblade]
- Treat an MPO with too few MP entries as a JPEG #9826 [@LuShadowX]
- Use mode as default for C getpalette raw mode #9822 [@radarhere]
- Raise SyntaxError instead of OverflowError for oversized JPEG 2000 box #9818 [@nevercodecorrect]
- Raise UserWarning if TIFF tag offset too large #9816 [@radarhere]
- Raise ValueError if Dib paste() box does not match image size #9815 [@radarhere]
- Raise ValueError instead of asserting number of FTEX texture formats #9805 [@ritsth]
- Handle premultiplied alpha modes in ImageColor.getcolor() #9797 [@chuenchen309]
- Remove PIL_NO_INLINE and MSVC alias for inline #9802 [@akx]
- Fix adding a new color when image palette has missing background or transparency index #9799 [@chuenchen309]
- Correct background color when using P mode images with ImageOps.pad() #9795 [@chuenchen309]
- Fix 16-bit ImageFilter accuracy #9786 [@akx]
- Removed unused variable #9789 [@radarhere]
- Remove unused PNG _OUTMODES #9780 [@radarhere]
- Add support for Python 3.15 #9776 [@hugovk]
- Fix RLE4 absolute mode decoding for odd pixel counts #9710 [@nyxst4ck]
- Avoid divide-by-zero crash in RankFilter #9755 [@lukegb]
- Port coveragerc to pyproject.toml; omit benchmarks from coverage #9771 [@akx]
- Remove minimumReleaseAge for google/oss-fuzz #9764 [@radarhere]
- Use ImagingNewDirty() in RankFilter and remove ImagingFill() in font.getmask() #9744 [@akx]
- Remove Setuptools obsolete
zip_safe flag #9758 [@hugovk]
- Fix attach SBOM to GitHub release #9748 [@hugovk]