Why do transparent edges fringe after resizing or blending, and does my library premultiply for me?
Filtering straight-alpha RGBA bleeds the colour of invisible pixels into visible edges; Pillow (9de06c8a) avoids this by converting RGBA to premultiplied RGBa for resize (all filters except NEAREST) and reduce, then converting back. Un-premultiplying fails where alpha is 0 (OpenEXR), and PNG says compositing should use linear intensity, not gamma-encoded values.
Filtering straight-alpha RGBA bleeds the colour of invisible pixels into visible edges; Pillow (9de06c8a) avoids this by converting RGBA to premultiplied RGBa for resize (all filters except NEAREST) and reduce, then converting back. Un-premultiplying fails where alpha is 0 (OpenEXR), and PNG says compositing should use linear intensity, not gamma-encoded values.
Curator qualifications: Specifications and code read 2026-10-22; no images processed (the producer experiment was not re-run). Producer experiment separating library behaviours not re-run.
Limitations: Specifications and code read 2026-10-22; no images processed (the producer experiment was not re-run).
Evidence status: statements located in the cited sources by a correlated desk review (Claude); not executed; not independently reviewed.
Structured fields
{
"citations": [
{
"url": "https://www.w3.org/TR/png-3/",
"note": "Pillow 9de06c8a src/PIL/Image.py L2415-L2418 (resize) and L2468-L2471 (reduce); OpenEXR TechnicalIntroduction.rst L1262-L1274; W3C PNG-3 Alpha channel processing"
},
{
"url": "https://github.com/AcademySoftwareFoundation/openexr/blob/dbdc101a3b754ee21f0e70ed28ffec1cba32c78e/website/TechnicalIntroduction.rst",
"note": "Pillow 9de06c8a src/PIL/Image.py L2415-L2418 (resize) and L2468-L2471 (reduce); OpenEXR TechnicalIntroduction.rst L1262-L1274; W3C PNG-3 Alpha channel processing"
},
{
"url": "https://github.com/python-pillow/Pillow/blob/9de06c8a53ab71e724edc84cf59bbf843c973984/src/PIL/Image.py",
"note": "Pillow 9de06c8a src/PIL/Image.py L2415-L2418 (resize) and L2468-L2471 (reduce); OpenEXR TechnicalIntroduction.rst L1262-L1274; W3C PNG-3 Alpha channel processing"
}
]
}Evidence claims
- [sourced_fact] Filtering straight-alpha RGBA bleeds the colour of invisible pixels into visible edges; Pillow (9de06c8a) avoids this by converting RGBA to premultiplied RGBa for resize (all filters except NEAREST) and reduce, then converting back. Un-premultiplying fails where alpha is 0 (OpenEXR), and PNG says compositing should use linear intensity, not gamma-encoded values. · locator: Pillow 9de06c8a src/PIL/Image.py L2415-L2418 (resize) and L2468-L2471 (reduce); OpenEXR TechnicalIntroduction.rst L1262-L1274; W3C PNG-3 Alpha channel processing source
Rights
| component | license | hosting | redistribution | modification | training | Evidence and notes |
|---|---|---|---|---|---|---|
| documentation | unknown | permitted | permitted | unknown | unknown | Applies to this original summary only, not to the cited sources. |