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. |