Skip to content

Conversation

@Pinta365
Copy link
Member

Problem

The GIF encoder did not properly support animated GIFs with partial frames (frames smaller than the
canvas that are positioned at an offset). This caused animated GIF round-trips to produce corrupted
output.

Issues:

  1. Frame position (left, top) was always set to (0, 0)
  2. Frame dimensions always used canvas size instead of actual frame size
  3. Alpha channel was ignored, breaking transparency in partial frames
  4. Disposal method from input was not preserved

Solution

src/utils/gif_encoder.ts

  1. Added GIFFrameData interface with frame metadata (left, top, width, height, disposal)

  2. Updated addFrame() signature to accept optional frame metadata:

    addFrame(data, delay, { left, top, width, height, disposal });
  3. Updated quantize() to handle transparency:

    • Detects transparent pixels (alpha < 128)
    • Reserves palette index 0 for transparency
    • Uses actual frame dimensions instead of canvas dimensions
  4. Updated encode() to use frame metadata:

    • Writes correct frame position and dimensions in Image Descriptor
    • Sets transparency flag in Graphic Control Extension when needed
    • Preserves disposal method from frame metadata

src/formats/gif.ts

  1. Updated encodeFrames() to pass frame metadata to encoder
  2. Added mapDisposalMethodToNumber() helper function

Backward Compatibility

The changes are backward compatible. The addFrame() method still works with just (data, delay) -
frame metadata is optional with sensible defaults.

@Pinta365 Pinta365 merged commit 8455291 into main Dec 28, 2025
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