Skip to content

Reduce an animated input to its first frame [patch] - #137

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/119-single-frame-output
Oct 8, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/119-single-frame-output

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #119

What was wrong

Image.Load<Rgba32> decodes every frame of an animated GIF, APNG or WebP. The Mutate calls (BlackWhite, crop/pad/resize) run on every frame. FindBrightestOpaqueValue and FlattenToCoverageAndMeasureBounds go through ProcessPixelRows, which only touches the root frame. So only frame 0 got the coverage pass. The other frames were saved as an animated PNG of raw greyscale, cropped to frame 0's bounding box, and the run still reported success.

Change

ProcessImage now removes every frame after the first before it does anything else, so the output is always a single-frame coverage mask. That is the tool's documented output, and the triage recommended this approach. Doing it inside ProcessImage rather than in ProcessDirectory keeps it covered by unit tests.

Tests

ProcessImageTests.ReducesAnAnimatedInputToItsFirstFrame is the two-frame fixture from the issue:

  • frame 0 has a 20×20 square
  • frame 1 has a 55×55 square

The test asserts there is one output frame, its width is 20 (frame 0's bounds), and its pixels are the red target colour. It failed before the fix (Frames.Count was 2) and passes with it.

Full suite: 79/79 pass. The gold-master tests need the LFS fixtures (git lfs pull). Without them, the 8 gold-master cases fail on main too.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LbAGNxbUT888WNAYAvXC2p


Generated by Claude Code

An animated GIF, APNG or WebP loads with one frame per step. The Mutate calls
applied to every frame, but the coverage pass in ProcessPixelRows touched only
the root frame, so the remaining frames were written out as an animated PNG of
raw greyscale cropped to the first frame's bounds. ProcessImage now drops every
frame after the first before processing, matching the tool's single-frame
output.

Fixes #119

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LbAGNxbUT888WNAYAvXC2p
@sonarqubecloud

sonarqubecloud Bot commented Oct 7, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 9a17908 into main Oct 8, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix/119-single-frame-output branch October 8, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Animated inputs (GIF/APNG/WebP) produce an animated PNG whose frames after the first are not recoloured

2 participants