Repository navigation
fix(image): keep animation frames in AVIF, both ways - #1230
Open
KnifeLemon wants to merge 3 commits into
Open
KnifeLemon wants to merge 3 commits into
KnifeLemon wants to merge 3 commits into
Conversation
An animated GIF or WebP became one still AVIF, because AVIF wasn't among the formats whose frames are an animation. The bundled ImageMagick already writes several frames as an AVIF image sequence and reads one back, so AVIF joins that list and needs no FFmpeg. Still pictures take the same path as before. An animated AVIF now also stays animated as GIF, WebP or APNG and gives one picture for other targets, instead of one file per frame. On the way to video an AVIF still counts as a photo, so photos don't go through a 256-colour GIF. Playback speed applies to AVIF too. Fixes #1200 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An AVIF sequence has one alpha track, and ImageMagick stores a frame without an alpha channel as fully transparent in it, so an opaque first frame of a GIF, WebP or MNG that turns transparent later vanished. Every frame now gets the channel when any frame is transparent, and none when all are opaque, so opaque animations carry no alpha track. Every multi-item AVIF was also taken for an animation: a burst lost its other pictures as PNG or JPG, and items of other sizes were cropped or laid over the first. An AVIF now counts as an animation only with the major brand "avis" and a moov box, and any other AVIF takes the same paths as on main. The tests build multi-item AVIFs in memory, read frames back pixel by pixel, and cover delays of zero and resizing and turning an animation. Refs #1200 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes #1200
Animated GIF and WebP → AVIF came out as one still frame, because AVIF wasn't in
ImageEncoder.Animated.What changed
avisbrand, with a still primary item for viewers that don't play sequences), so this needs no new route or engine. FFmpeg'savifmuxer with libaom-av1 or libsvtav1 also works, but as an optional engine it would have left most users with a still picture.ImageEncoder.MatchAlphagives every frame the channel when any frame is transparent, and none when all are opaque, so an opaque animation (also from an APNG, whose frames all have the channel) gets no alpha track.frames[i].Writepath as before. A test checks the bytes equal a direct ImageMagick write at the preset's quality.AvifSequence.IsSequencelooks at the file, in the spirit ofApng.IsAnimated: major brandavisand amoovbox. Such a file is read as its own source format, so a plainavifsource takes the same code paths as on main. A burst, a visible gain map or items of their own sizes stay separate_pNpictures, not cropped, not laid over each other, and not turned into an animation._pNfile or PDF page per frame.ImageEncoder.Edgeis unchanged and still prices AVIF → GIF/APNG as a still picture, so AVIF photos keep reaching video through a full-colour PNG. The cost is that an animated AVIF → MP4 is now a video of its first frame (before, it made one video per frame).docs/ENGINES.mddescribes all this.Limits
These are accepted for this PR:
repetitionCount = Infinityfor these files.-cpu-used 6 -crf 32heic:speedbarely changes the time (write alone: 8 was about 30 s), so the default stays.collection.Writehas no cancellation, so cancelling waits for it to finish. That matters more here because a long GIF takes minutes.How it was tested
AnimatedAvifTests(42 cases, inputs generated in code, 42 passed): frame count, delays including zero,avisbrand, resize and rotation on an animation, transparency, opaque frames before transparent ones read back pixel by pixel from GIF, WebP and MNG, no alpha track on opaque animations from GIF, WebP and APNG, quality, playback speed, TIFF pages, the reverse direction, PDF and routes. With FFmpeg present,ffmpegdecodes the frames itself and an FFmpeg-written AVIF is converted.AvifBuilderbuilds multi-item AVIFs in memory, so no sample files are added. They cover a burst, a larger second item, a smaller second item, and theavisbrand without tracks. A smaller item stands in for a visible gain map; those tests don't build the gain-map boxes themselves.MatchAlphaand the sequence check both switched off, 16 of the then 41 cases failed.AnimationSpeedTests,ApngTests,HeicTestsand the video route tests, together withAnimatedAvifTests: 82 passed.ImageFormatTests,ImageAndPdfTests,ImageToolTestsandMetadataTests: 126 passed, 51 skipped (all 51 are inMetadataTests, from the merged main).Preset_editor_shows_playback_speed_only_for_targets_that_keep_animationslast ran before these fixes and merging main, and its code didn't change.ImageDecoder:_p1and_p2. The hidden-thumbnail file and a plain still gave one file.dotnet format --verify-no-changeson the changed code files.Not tested: Linux and macOS (CI runs the tests there), Safari, Firefox, Windows' own Photos app, and a sequence → HEIC (it uses the same check as PDF, which is tested). Only targeted test classes were run locally, not the whole suites. "As on main" for multi-item files rests on the code paths and the reviewer's report of main, not on a side-by-side run against a main build.
🤖 Generated with Claude Code