PeachImage

PeachImage

AnimatedImage Class

An in-memory, fully-decoded (or to-be-encoded) animated image: an ordered sequence of composited AnimatedImageFrames plus loop count. Codec-agnostic, mirroring Image: Load(Stream, DecoderOptions) and Save(Stream, string, EncoderOptions) dispatch to whichever of Image’s built-in codecs also support animation (GIF today), rather than any single format’s animation API being called directly.

public sealed class AnimatedImage

Inheritance System.Object → AnimatedImage

Remarks

Does not implement System.IDisposable: a decode-produced Frames sequence is lazy and may be backed by an open stream, so nothing meaningful is owned at the AnimatedImage level to dispose.

A decode-produced Image pulled from Frames is a live view into decoder-internal state, not an independent copy: the frame compositor reuses a single persistent canvas across the whole animation for performance, so each frame’s Image is only valid until the next frame is pulled from the same enumeration (the next MoveNext()/loop iteration). Reading pixel data (GetPixelSpan(), GetRowSpan(int), PixelMemory) on an invalidated frame throws System.InvalidOperationException. If you need to retain a frame beyond that point — e.g. to collect every frame before processing them, or to keep the previous frame around while inspecting the current one — call Clone() (or Clone() on just the pixel data) before advancing: foreach (var frame in animated.Frames) { var kept = frame.Clone(); ... }. A frame pulled directly from Frames aliases decoder-internal state rather than owning a pooled buffer, so disposing its Image is unnecessary (a safe no-op if done anyway); a Clone()d frame’s Image does own a pooled buffer and may be disposed for best pooling behavior, though — same as elsewhere in this library — that’s an opt-in performance choice, not a correctness requirement.

Constructors  
AnimatedImage(IEnumerable<AnimatedImageFrame>, int, int, int) Initializes a new instance of AnimatedImage.
Properties  
Frames The frames of this animation, in display order. May be a lazily-decoded, single-pass sequence backed by an open stream — enumerate once; pass a System.Collections.Generic.List<>/array to the constructor instead if you need to enumerate more than once.
Height The canvas height, in pixels (shared by every frame).
LoopCount How many times the animation should repeat; 0 means loop forever.
Width The canvas width, in pixels (shared by every frame).
Methods  
Load(string, DecoderOptions) Loads an animated image from path, auto-detecting its format.
Load(Stream, DecoderOptions) Loads an animated image from stream, auto-detecting its format by sniffing its header bytes.
Resize(int, int, ResizeOptions) Creates a resized copy of this animation: every frame resized to the given dimensions using the same resampling filter, same loop count and per-frame timing/disposal. Lazy, like Frames itself — each frame is resized on demand as it’s pulled, not all at once. When options’s Mode is Max and this animation’s canvas already fits within width x height, returns this same instance unchanged rather than resizing every frame for no reason.
Save(string, EncoderOptions) Encodes this animated image and writes it to path, inferring the format from the file extension.
Save(Stream, string, EncoderOptions) Encodes this animated image as formatName and writes it to stream.