https://pillow.readthedocs.io/en/stable/releasenotes/12.3.0.html
Removals
- Remove non-image ImageCms modes #9697 [@radarhere]
Documentation
- Add release notes for SBOM and performance improvements #9747 [@radarhere]
- Add security release notes #9741 [@radarhere]
- Add release notes for Python 3.15 beta wheels #9696 [@radarhere]
- ImageFont can also be used with ImageText #9597 [@radarhere]
- Additional guidelines for security reports #9659 [@wiredfool]
- Fixed typo #9636 [@radarhere]
- Added CVEs to 12.2.0 release notes #9591 [@radarhere]
- Revise development support information in README #9583 [@aclark4life]
- Add INCIDENT_RESPONSE.md #9555 [@aclark4life]
- Add STRIDE threat model to security docs #9562 [@aclark4life]
- Add CVEs to 12.2.0 release notes #9556 [@radarhere]
- Update README with revised security policy #9553 [@radarhere]
- Update security policy #9552 [@aclark4life]
- Update macOS tested Python versions #9534 [@radarhere]
Dependencies
- Update dependency harfbuzz to v14.2.1 #9720 [@renovate[bot]]
- Update dependency mypy to v2 #9653 [@renovate[bot]]
- Update dependency cibuildwheel to v4 #9665 [@renovate[bot]]
- Update github-actions #9655 [@renovate[bot]]
- Update dependency libavif to v1.4.2 #9652 [@renovate[bot]]
- Update dependency lcms2 to v2.19.1 #9651 [@renovate[bot]]
- Update dependency check-jsonschema to v0.37.2 #9650 [@renovate[bot]]
- Update google/oss-fuzz digest to d872252 #9614 [@renovate[bot]]
- Update dependency lcms2 to v2.19 #9609 [@renovate[bot]]
- Update dependency libpng to v1.6.58 - autoclosed #9608 [@renovate[bot]]
- Update dependency harfbuzz to v14 #9610 [@renovate[bot]]
- Update dependency mypy to v1.20.2 #9599 [@renovate[bot]]
- Update github-actions #9611 [@renovate[bot]]
- Update dependency cibuildwheel to v3.4.1 #9607 [@renovate[bot]]
- Move dependency versions to single JSON and enable Renovate #9559 [@hugovk]
- Updated raqm to 0.10.5 #9557 [@radarhere]
- Update dependency cibuildwheel to v3.4.0 #9532 [@renovate[bot]]
Testing
- Remove matrix.os from benchmark #9735 [@radarhere]
- Remove references to libavif patch #9734 [@radarhere]
- Add benchmark tests #9654 [@akx]
- Use reshape() instead of setting NumPy array shape directly #9728 [@radarhere]
- Add dependencies.json to Windows cache key #9721 [@radarhere]
- Increase AVIF test epsilon for loong64 #9714 [@wszqkzqk]
- Add colour to Linux and Windows wheel build logs #9677 [@hugovk]
- Do not test NumPy against Python 3.15 Windows AMD64 wheels #9674 [@radarhere]
- Run pyroma in
tox -e lintinstead of pytest #9670 [@hugovk] - Update Ghostscript to 10.7.1 #9634 [@radarhere]
- Update free-threading CI #9625 [@hugovk]
- Increase AVIF test epsilon for riscv64 #9606 [@radarhere]
- Add Fedora 44 #9594 [@radarhere]
- Test Ubuntu 26.04 LTS (Resolute Raccoon) #9587 [@hugovk]
- Skip EPS test_1 for Ghostscript 10.06.0 #9588 [@radarhere]
- Catch subprocess.CalledProcessError in test_grab_x11 #9578 [@radarhere]
- Correct feature name #9542 [@radarhere]
- Skip test if FreeType is not available #9540 [@radarhere]
- Remove type hint ignore #9538 [@radarhere]
- Update macOS tested Python versions #9534 [@radarhere]
- Remove Debian 12 and Fedora 42 from CI #9530 [@hugovk]
- Remove manylinux2014 and Amazon Linux 2 #9528 [@radarhere]
Type hints
- Use NumPy 2.4.6 for mypy #9705 [@radarhere]
- Update dependency mypy to v2 #9653 [@renovate[bot]]
- Update putpixel type hint to allow lists in xy #9585 [@radarhere]
- Remove type hint ignore #9538 [@radarhere]
Other changes
- Speed up ImageChops operations #9738 [@akx]
- Speed up
Image.filter()#9736 [@akx] - Speed up
Image.getchannel(),Image.merge(),Image.putalpha()andImage.split()#9675 [@akx] - Speed up
Image.fill(),Image.linear_gradient()andImage.radial_gradient(). #9737 [@akx] - Speed up
Image.resample()#9739 [@akx] - Speed up
alpha_composite,matrix,negative,quantize#9740 [@akx] - Remove PyErr_Clear() of "weird" exceptions #9730 [@radarhere]
- Check realloc return value #9722 [@radarhere]
- Add max_length to PdfStream decode() #9718 [@radarhere]
- Return early when there is no fill region #9732 [@radarhere]
- Allow error to be raised if PyDict_SetItemString fails #9731 [@radarhere]
- Speed up
Image.blend()#9649 [@akx] - Raise OverflowError if number of vertices is too large for Path #9729 [@radarhere]
- Remove unused HSV and LAB matrix conversion from C #9724 [@radarhere]
- Prevent reusing ImagingDecoderObject.setimage #9656 [@Serotav]
- Raise ValueError if FPX tile size is not 64px by 64px #9660 [@radarhere]
- Only clear error if it is BufferError #9727 [@radarhere]
- Apply XOR mask to 1 and L mode CUR images #9641 [@radarhere]
- Do not raise error from unknown channel ID when parsing PSD layers #9644 [@radarhere]
- Raise ValueError if P;2L or P;4L data is truncated in frombytes() #9725 [@radarhere]
- Embed SBOM into wheels #9679 [@hugovk]
- Do not set eval() globals in ImageMath.unsafe_eval() #9576 [@radarhere]
- Add Tcl/Tk license to wheels #9663 [@radarhere]
- Ensure map stride is at least one full row of pixels #9719 [@radarhere]
- Raise OverflowError if text width exceeds INT_MAX #9717 [@radarhere]
- Raise error if image modes do not match ImageCms transform modes #9715 [@radarhere]
- Use int64_t for text height #9716 [@radarhere]
- Return if error occurs in Py_mod_exec slot #9712 [@radarhere]
- Add decompression bomb checks to FontFile classes #9711 [@radarhere]
- If C error is raised, return NULL #9706 [@radarhere]
- Prevent saving 1 mode images as TGA with run-length encoding #9709 [@radarhere]
- Raise ValueError if EPS BeginBinary bytecount is negative #9708 [@radarhere]
- Do not DECREF tuple until tuple items are no longer used #9707 [@radarhere]
- Do not update NumPy automatically #9713 [@radarhere]
- Simplified code #9642 [@radarhere]
- If realloc fails, do not reduce block size #9702 [@radarhere]
- DECREF PyDict_GetItemRef result #9701 [@radarhere]
- Use int64_t to calculate paste box dimensions #9703 [@radarhere]
- Calculate JPEG2000 total_component_width for each tile in isolation #9704 [@radarhere]
- Raise ValueError if value is not bytes for TIFF_BYTE or TIFF_ASCII tag #9699 [@radarhere]
- Release Py_Buffer on error #9698 [@radarhere]
- Use os.startfile() in WindowsViewer show_file() #9692 [@radarhere]
- Validate large filter sizes when initializing RankFilter #9695 [@radarhere]
- Add decompression bomb check to GdImageFile #9693 [@radarhere]
- Free image bands when an error occurs while splitting an image #9694 [@radarhere]
- Check PyList_Append return value #9690 [@radarhere]
- Check WebPMuxNew return value #9689 [@radarhere]
- Check PyCapsule_New return value #9691 [@radarhere]
- Do not return negative width for text length #9623 [@radarhere]
- Add args argument to METH_NOARGS methods #9687 [@radarhere]
- Check ImagingNewDirty return value #9688 [@radarhere]
- Use int64_t for text width #9686 [@radarhere]
- Move PyDateTime_IMPORT inside Py_mod_exec slot #9580 [@radarhere]
- Validate size and rank when initializing RankFilter #9661 [@radarhere]
- Raise ValueError if insufficient data is read from DDS RGB file #9405 [@radarhere]
- Correct
IFDRational.__float__()return value #9676 [@nyxst4ck] - Correct length when accessing ImagePath.Path subscript #9685 [@radarhere]
- Release reference on non-flattened sequence error #9684 [@radarhere]
- Do not release Py_buffer until buf is no longer in use #9683 [@radarhere]
- Do not resize macOS retina screenshots by default #9266 [@radarhere]
- Add abstract BaseImageFont class #9595 [@radarhere]
- Cast before multiplying #9678 [@radarhere]
- Limit radius to half width or height of rounded rectangle #9561 [@radarhere]
- linesize is always xsize multiplied by pixelsize #9647 [@radarhere]
- Check annotate_hash_table return value #9572 [@radarhere]
- Catch KeyError when checking mode from PNG IHDR chunk #9604 [@radarhere]
- Only pass one argument to C expand #9664 [@radarhere]
- Raise error if declared JPEG2000 marker length is too small #9666 [@radarhere]
- In _dump(), use Python PPM save, instead of C #9566 [@radarhere]
- Raise error consistently from inside ImagingNewArrow #9571 [@radarhere]
- Simplify
RankFilter.ccheck #9662 [@radarhere] - Support opening and saving L mode AVIF images with libavif >= 1.3.0 #9471 [@radarhere]
- [pre-commit.ci] pre-commit autoupdate #9648 [@pre-commit-ci[bot]]
- Apply libtiff patch to fix CVE-2026-4775 #9646 [@radarhere]
- Remove duplicate code #9640 [@radarhere]
- Switch iOS back to macos-26-intel #9631 [@radarhere]
- Don't use list as default in PdfParser read_prev_trailer #9629 [@danigm]
- Add support for Python 3.15 #9624 [@radarhere]
- Do not draw line or arc if width is zero #9589 [@radarhere]
- Use _accept check in WebP _open #9605 [@radarhere]
- Compare dist sizes vs latest PyPI release #9621 [@hugovk]
- Do not generate SBOM in scheduled run on fork #9620 [@radarhere]
- Use plugin method directly when saving PDFs #9547 [@radarhere]
- [pre-commit.ci] pre-commit autoupdate #9617 [@pre-commit-ci[bot]]
- Set Renovate prCreation to not-pending #9616 [@radarhere]
- Raise error if PNG transparency has incorrect type or length when saving #9536 [@radarhere]
- If PdfParser buffer is memoryview, release it when closing #9596 [@radarhere]
- Correct integer overflow in 16-bit resampling #9480 [@hayatoikoma]
- SBOM: Use real versions from dependencies.json #9593 [@hugovk]
- Restrict SBOM upload to only Pillow JSON #9598 [@radarhere]
- Generate CycloneDX SBOM at release time via CI #9550 [@aclark4life]
- Raise ValueError if ImageOps border has unsupported format #9426 [@veeceey]
- Unsafe pointer dereference from unchecked Python integer in Tk initialization #9548 [@barttran2k]
- Reorder renovate.json #9565 [@radarhere]
- Add python-pillow GitHub Sponsors to FUNDING.yml #9563 [@aclark4life]
- Correct environment URL #9558 [@radarhere]
- Remove or protect secrets in Actions #9544 [@pre-commit-ci[bot]]
- Move Homebrew dependencies into Brewfile #9546 [@hugovk]
- Do not precompute horizontal coefficients if not horizontal resizing #9543 [@radarhere]
- Fix comparison warnings #9541 [@radarhere]
- Close PdfParser if error occurs during init #9539 [@radarhere]
- Drop experimental Python 3.13 free-threaded wheels #9535 [@radarhere]
- Update github-actions #9533 [@renovate[bot]]