PeachImage
PeachImage
Image Class
An in-memory, single-frame, tightly-packed pixel buffer decoded from (or destined for) an image file.
public sealed class Image : System.IDisposable
Inheritance System.Object → Image
Implements System.IDisposable
Remarks
Implements System.IDisposable because most instances rent their pixel buffer from a shared System.Buffers.ArrayPool<> and return it on Dispose(). Disposal is an opt-in performance mechanism, not a correctness requirement: an un-disposed Image’s buffer is simply garbage-collected like any other array, with no leak or corruption risk — but disposing promptly lets the pool reuse that buffer for the next decode/resize, which matters most under concurrent load (e.g. a service processing many uploads at once). Images produced by Frames (as opposed to Clone()) don’t own a pooled buffer at all — they alias decoder-internal state — so Dispose() on those is always a safe no-op.
| Properties | |
|---|---|
| HasAlpha | Whether this image’s source actually carries an alpha channel — not whether its format could ever have one (see CanDecodeTransparency for that), and computed from the source’s own header/chunk metadata rather than by scanning pixel data. Reflects the source, not the final PixelFormat: converting an opaque source to a target format with an alpha channel (or an alpha-bearing source down to one without) via TargetPixelFormat doesn’t change this value. Always false for images not produced by a codec’s Decode path (e.g. Create(int, int, PixelFormat)). |
| Height | The image height, in pixels. |
| IsAnimated | Whether this Image was decoded from a multi-frame animated source (only its first frame was decoded — see AnimatedImage to decode every frame). Always false for images not produced by a codec’s Decode path (e.g. Create(int, int, PixelFormat)). |
| Metadata | Metadata (EXIF/ICC/etc.) captured alongside the pixel data, if any. |
| PixelFormat | The pixel buffer’s layout. |
| PixelMemory | Gets the entire tightly-packed pixel buffer as System.Memory<>, for async/non-span consumers. |
| SupportedFormats | Capability and identity metadata for every format PeachImage has a built-in codec for. |
| Width | The image width, in pixels. |
| Methods | |
|---|---|
| Clone() | Creates an independent copy of this image’s pixel data and metadata. Use this to retain a frame pulled from Frames beyond the point where it would otherwise be invalidated by advancing to the next frame. |
| ConvertToSrgb() | Color-manages this image using its own embedded ICC profile (GetIccColorProfile()), producing a new Rgba32Image — the high-level convenience over ConvertToSrgb(ReadOnlySpan<byte>, Span<byte>, int, Nullable<IccRenderingIntent>, bool) for the common case of “just color-manage this image for me.” A missing or unusable embedded profile is a normal, expected outcome (most images don’t carry one) rather than an error: when there’s nothing to convert — no usable profile, its channel count doesn’t match this image’s own pixel format, or PixelFormat isn’t one ICC conversion applies to (it’s already Rgba32, for instance) — this same instance is returned unchanged rather than throwing or allocating a needless copy, the same “may return this” contract Resize(int, int, ResizeOptions) documents (see its own remarks for the disposal implications of that). |
| Create(int, int, PixelFormat) | Allocates a new, uninitialized image of the given dimensions and pixel format. The backing buffer is rented from a shared pool — see the type-level remarks on disposal. |
| Dispose() | Returns this image’s pixel buffer to its pool, if it owns one (see the type-level remarks on disposal). Safe to call more than once. After calling this, GetPixelSpan(), GetRowSpan(int), and PixelMemory throw System.ObjectDisposedException. |
| GetFormatInfo(string) | Looks up capability and identity metadata for the format named formatName. |
| GetPixelSpan() | Gets a zero-copy view of the entire tightly-packed pixel buffer. |
| GetRowSpan(int) | Gets a zero-copy view of a single scanline. |
| Identify(Stream) | Reads image dimensions and format information from stream without fully decoding pixel data. |
| Load(string, DecoderOptions) | Loads an image from path, auto-detecting its format. |
| Load(Stream, DecoderOptions) | Loads an image from stream, auto-detecting its format by sniffing its header bytes. |
| Load(ReadOnlySpan<byte>, DecoderOptions) | Loads an image from an in-memory buffer, auto-detecting its format by sniffing its header bytes. Decodes directly from data’s pinned memory via System.IO.UnmanagedMemoryStream — no intermediate copy, unlike wrapping a System.IO.MemoryStream around data.ToArray(). |
| LoadAsync(Stream, DecoderOptions, CancellationToken) | Asynchronously loads an image by buffering stream and then decoding it synchronously (decoding itself is CPU-bound, not I/O-bound). |
| Resize(int, int, ResizeOptions) | Creates a resized copy of this image using the given target dimensions and resampling filter. Does not modify this instance (same non-mutating contract as Clone()) — except when options’s Mode is Max and this image already fits within width x height, or when it’s Crop/Pad and this image is already exactly width x height, in which case this same instance is returned unchanged rather than allocating a needless copy. Because of that fast path, the returned Image may be <em>this same instance</em> rather than an independent one — disposing one of the two references then makes the other throw System.ObjectDisposedException on its next access, same as disposing any other shared reference twice would. If you need the source and the resized result to have independent lifetimes regardless of which path is taken, dispose only after you’re done with both, or check System.Object.ReferenceEquals(System.Object,System.Object) first. |
| Save(string, EncoderOptions) | Encodes this image and writes it to path, inferring the format from the file extension. |
| Save(Stream, string, EncoderOptions) | Encodes this image as formatName and writes it to stream. |
| SaveAsync(string, EncoderOptions, CancellationToken) | Encodes this image and writes it to path, inferring the format from the file extension. Encoding itself is synchronous and CPU-bound, same as LoadAsync(Stream, DecoderOptions, CancellationToken)’s decode — only the file write is awaited. |
| SaveAsync(Stream, string, EncoderOptions, CancellationToken) | Encodes this image as formatName and writes it to stream. Encoding itself is synchronous and CPU-bound, same as LoadAsync(Stream, DecoderOptions, CancellationToken)’s decode — only the write to stream is awaited. |
| TryLoad(Stream, Image, DecoderOptions) | Attempts to load an image from stream, returning false instead of throwing on failure. |