Skip to content

Fix animated WebP crop artifacts#47

Merged
loks0n merged 2 commits into
mainfrom
fix/animated-webp-crop
Jul 20, 2026
Merged

Fix animated WebP crop artifacts#47
loks0n merged 2 commits into
mainfrom
fix/animated-webp-crop

Conversation

@ChiragAgg5k

@ChiragAgg5k ChiragAgg5k commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

  • crop animated images by coalescing frames first, then resizing each full frame, then deconstructing — previously only GIF got this treatment
  • animated WebP (and any other multi-frame format) was resized as static frames, which scaled delta/partial frames independently and produced blocky ghosting artifacts
  • add a regression fixture + test that asserts correct per-frame colors after cropping an animated WebP with dirty rectangles

Before / After

Resizing an animated WebP without coalescing scaled each delta/partial frame independently, which produced blocky ghosting. After this fix, frames are coalesced before resize so mid-animation frames stay clean.

Before (broken remote resize) After (fixed coalesce + crop)
Before: blocky/ghosting artifacts on frame 10 After: clean frame 10 after coalesce + crop

Frame 10 from an animated WebP resized to height 256 (broken remote preview vs fixed local crop path).

Testing

  • ./vendor/bin/phpunit --filter 'test_crop_animated_webp_preserves_frames|test_crop100x100_gif|test_gif_small_last_frame|test_crop_gravity' (31 tests, 180 assertions)
  • composer lint
  • composer check

GIF already coalesced before resize; animated WebP took the static path and scaled delta frames independently, causing blocky ghosting. Use the same coalesce/deconstruct path for any multi-frame image.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ChiragAgg5k
ChiragAgg5k marked this pull request as ready for review July 20, 2026 15:55
@greptile-apps

greptile-apps Bot commented Jul 20, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes crop handling for animated WebP and other multi-frame images. The main changes are:

  • Coalesce multi-frame images before cropping each frame.
  • Reset cropped frame pages to the target canvas size.
  • Avoid deconstructing frames after crop.
  • Add animated WebP and hold-frame crop tests.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
src/Image/Image.php Updates crop logic so multi-frame images are processed frame-by-frame after coalescing, without deconstructing the result.
tests/Image/ImageTest.php Adds tests for animated WebP crop output and preserved playback delay for repeated hold frames.
tests/resources/disk-a/anim-delta.webp Adds an animated WebP fixture for dirty-rectangle crop coverage.

Reviews (2): Last reviewed commit: "fix: skip deconstruct after animated cro..." | Re-trigger Greptile

Comment thread src/Image/Image.php Outdated
deconstructImages() can collapse identical pause frames into empty deltas that WebP encoding drops, zeroing playback delay. Keep coalesced frames and assert total delay is preserved.

Co-authored-by: Cursor <cursoragent@cursor.com>
@loks0n
loks0n merged commit 652367d into main Jul 20, 2026
5 checks passed
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.

2 participants