Use info disposal and blend when calculating APNG frame deltas - #10061
Open
glaziermag wants to merge 2 commits into
Open
glaziermag wants to merge 2 commits into
glaziermag wants to merge 2 commits into
Conversation
When disposal or blend were not passed to save(), the fcTL chunk used the im.info fallback, but the frame delta assumed OP_NONE and OP_SOURCE, so frames were cropped against the wrong base image. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member
|
Is there any particular reason there's no test for |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
If
disposalorblendis not passed tosave(), the APNG writer uses theim.infovalue for the fcTL chunk (L1306-L1307). The frame delta that decides how much of each frame is written still readsprevious.encoderinfo.get("disposal")(L1236-L1237), which isNonethere, so it assumesOP_NONE. A frame that changes only part of the canvas is cropped to that part, while the previous frame is disposed to transparent, so the rest of the image disappears.Since
Image.open()setsinfo["disposal"], this also affects re-saving an opened APNG.Image.open("Tests/images/iss634.apng").save(out, save_all=True)currently changes 40 of the 41 rendered frames. With this change, it round-trips unchanged.Changes proposed in this pull request:
disposalandblenddefaults that are written to the fcTL chunk. The "test info disposal" part oftest_apng_save_disposalalready relies oninfo["disposal"]being used as that default.OP_BACKGROUNDandOP_PREVIOUS.Tests/test_file_apng.pyandTests/test_file_png.pypass locally (Python 3.14, macOS).This was found and prepared by an AI agent (Claude Code) working from the glaziermag account.
Generated with Claude Code