ImageCollection Class
A disposable collection of images that are not animation frames: the pages of a document (TIFF, BigTIFF) or the alternative representations of a drawing (ICO, CUR). Entries may differ in size, pixel format and metadata, and are never resized or converted implicitly.
public sealed class ImageCollection : IDisposableRemarks
This type is deliberately separate from Image, whose frames are full-canvas displayed frames of one animation with a shared size and pixel format. Nothing converts one into the other implicitly: ImageCollectionEntry.Decode extracts an entry into a normal, independently owned Image, and ImageCollection.Add copies an image into the collection.
Loading is lazy and random access. Load reads only the directory structure of the container, so describing every entry costs a few kilobytes of reads whatever the size of the file; the pixels of an entry are read when that entry is decoded, each decode with its own limits and allocation scope. A collection therefore keeps its input open until it is disposed:
ImageCollection.Loadkeeps the file open for reading until the collection is disposed.ImageCollection.Loadneeds a seekable stream, which it keeps open (it does not own it) and seeks freely: the stream position after any call is unspecified. A non-seekable stream is rejected; read it into memory yourself if you must.ImageCollection.Loadcopies the data once, because the collection cannot retain a span.
Loaded entries can be decoded concurrently. ImageCollectionEntry.Decode may be called from several threads at once on the entries read from the input, the same entry or different ones: a file or in-memory collection reads at an offset, and a stream collection serializes its reads of the shared stream (the decoding itself still runs in parallel). The caller must not use a stream given to ImageCollection.Load while the collection is alive. Disposing the collection while an entry is decoding waits for the read in progress; the decode then completes or throws ObjectDisposedException. Editing the collection (ImageCollection.Add, Insert, Move, RemoveAt), Save and SaveAsync (until its task completes) are not thread-safe and must not overlap any other call.
Loading is synchronous. A random-access decoder issues many small reads whose offsets depend on the bytes just read, so an asynchronous variant would either await every tag or buffer the whole file. The asynchronous Image.LoadAsync and Image.IdentifyAsync entry points do buffer the whole input for these formats, which is why a large document should be read through this type.
- Implements
Properties
| Name | Description |
|---|---|
| Configuration | Gets the configuration used to load the collection and to decode its entries by default. |
| Count | Gets the number of entries. |
| Entries | Gets the entries, in container order. |
| Format | Gets the format the collection was loaded from, or ImageFormat.Unknown for a collection created in memory. |
| Kind | Gets what the entries are: document pages or alternative representations. |
Configuration
ImageCollection.csGets the configuration used to load the collection and to decode its entries by default.
public ImageConfiguration Configuration { get; }Property value
Count
ImageCollection.csEntries
ImageCollection.csGets the entries, in container order.
public IReadOnlyList<ImageCollectionEntry> Entries { get; }Property value
IReadOnlyList<ImageCollectionEntry>
Remarks
Entries are borrowed from the collection: they are valid until it is disposed or they are removed.
Format
ImageCollection.csGets the format the collection was loaded from, or ImageFormat.Unknown for a collection created in memory.
public ImageFormat Format { get; }Property value
Gets what the entries are: document pages or alternative representations.
public ImageCollectionKind Kind { get; }Property value
Indexers
| Name | Description |
|---|---|
| this[int] | Gets the entry at an index. |
this[int]
ImageCollection.csGets the entry at an index.
public ImageCollectionEntry this[int index] { get; }Parameters
indexint- The zero-based index.
Property value
Exceptions
ArgumentOutOfRangeException- The index is outside the collection.
Methods
| Name | Description |
|---|---|
| Add(Image, Point?) | Appends a copy of an image as the last entry. |
| Create(ImageCollectionKind, ImageConfiguration?) | Creates an empty collection to be filled with images and saved. |
| Dispose() | Releases the input of a loaded collection and the images of the entries that own one. Images returned by ImageCollectionEntry.Decode are owned by their caller and are not affected. |
| Insert(int, Image, Point?) | Inserts a copy of an image at an index. |
| Load(Stream, ImageConfiguration?) | Opens a multi-entry image from a seekable stream, starting at its current position. |
| Load(ReadOnlySpan<byte>, ImageConfiguration?) | Opens a multi-entry image from in-memory encoded data. |
| Load(string, ImageConfiguration?) | Opens a multi-entry image file and describes its entries without decoding any of them. |
| Move(int, int) | Moves an entry to another index, shifting the entries in between. |
| RemoveAt(int) | Removes an entry. An entry that owns a copied image releases it. |
| Save(Stream, ImageEncoder) | Encodes the collection to a stream, starting at its current position. The stream is left open. |
| Save(string, ImageEncoder?) | Encodes the collection to a file, published atomically. |
| SaveAsync(Stream, ImageEncoder, CancellationToken) | Asynchronously encodes the collection to a stream, starting at its current position. The stream is left open. |
| SaveAsync(string, ImageEncoder?, CancellationToken) | Asynchronously encodes the collection to a file, with the same atomic-publication guarantees as ImageCollection.Save. |
| SelectBySize(Size) | Selects the representation that best matches a requested size: the smallest entry at least as large as size in both directions, or, when none is large enough, the largest entry. Ties are broken by the highest stored bit depth, then by container order. |
Add(Image, Point?)
ImageCollection.csAppends a copy of an image as the last entry.
public ImageCollectionEntry Add(Image image, Point? hotspot = null)Parameters
imageImage- The image. It is copied; the caller keeps its own image and disposes it.
hotspotPoint?- The hotspot of a cursor representation, or
nullto use the hotspot of the frame ofimage(FrameMetadata.Hotspot), if it has one.
Returns
ImageCollectionEntry The new entry.
Exceptions
ArgumentExceptionimageis animated or has a poster frame: a page or a representation is a still image.ArgumentOutOfRangeExceptionhotspotis outside the image.ObjectDisposedException- The collection or the image is disposed.
Create(ImageCollectionKind, ImageConfiguration?)
ImageCollection.csCreates an empty collection to be filled with images and saved.
public static ImageCollection Create(ImageCollectionKind kind, ImageConfiguration? configuration = null)Parameters
kindImageCollectionKind- What the entries will be:
ImageCollectionKind.Pagesfor a document,ImageCollectionKind.Representationsfor an icon or a cursor. configurationImageConfiguration?- The configuration, or
nullforImageConfiguration.Default.
Returns
ImageCollection An empty collection owned by the caller.
Exceptions
Dispose()
ImageCollection.csReleases the input of a loaded collection and the images of the entries that own one. Images returned by ImageCollectionEntry.Decode are owned by their caller and are not affected.
public void Dispose()Insert(int, Image, Point?)
ImageCollection.csInserts a copy of an image at an index.
public ImageCollectionEntry Insert(int index, Image image, Point? hotspot = null)Parameters
indexint- The zero-based index, from 0 to
ImageCollection.Count. imageImage- The image. It is copied.
hotspotPoint?- The hotspot of a cursor representation, or
nullto use the hotspot of the frame ofimage(FrameMetadata.Hotspot), if it has one.
Returns
ImageCollectionEntry The new entry.
Exceptions
ArgumentOutOfRangeException- The index is outside the collection, or the hotspot is outside the image.
ArgumentExceptionimageis animated or has a poster frame.
Load overloads
Load(Stream, ImageConfiguration?)
ImageCollection.csOpens a multi-entry image from a seekable stream, starting at its current position.
public static ImageCollection Load(Stream stream, ImageConfiguration? configuration = null)Parameters
streamStream- The readable, seekable stream. It is left open and is seeked freely: its position after any call is unspecified.
configurationImageConfiguration?- The configuration, or
nullforImageConfiguration.Default.
Returns
ImageCollection The collection, owned by the caller.
Exceptions
ArgumentExceptionstreamis not readable, or is not seekable.UnknownImageFormatException- The format is not recognized.
UnsupportedImageFeatureException- The format is recognized but stores a single image.
InvalidImageContentException- The structure of the data is malformed or truncated.
Load(ReadOnlySpan<byte>, ImageConfiguration?)
ImageCollection.csOpens a multi-entry image from in-memory encoded data.
public static ImageCollection Load(ReadOnlySpan<byte> data, ImageConfiguration? configuration = null)Parameters
dataReadOnlySpan<byte>- The encoded data. It is copied once: the collection outlives the call and cannot retain a span.
configurationImageConfiguration?- The configuration, or
nullforImageConfiguration.Default.
Returns
ImageCollection The collection, owned by the caller.
Exceptions
UnknownImageFormatException- The format is not recognized.
UnsupportedImageFeatureException- The format is recognized but stores a single image.
InvalidImageContentException- The structure of the data is malformed or truncated.
ImageResourceLimitException- The data is longer than
ImageResourceLimits.MaxEncodedBytes.
Load(string, ImageConfiguration?)
ImageCollection.csOpens a multi-entry image file and describes its entries without decoding any of them.
public static ImageCollection Load(string path, ImageConfiguration? configuration = null)Parameters
pathstring- The path of the file. It stays open for reading until the collection is disposed.
configurationImageConfiguration?- The configuration, or
nullforImageConfiguration.Default.
Returns
ImageCollection The collection, owned by the caller.
Exceptions
ArgumentExceptionpathis empty.UnknownImageFormatException- The format is not recognized.
UnsupportedImageFeatureException- The format is recognized but stores a single image, or the file uses an unsupported feature.
InvalidImageContentException- The structure of the file is malformed or truncated.
ImageResourceLimitException- A configured limit is exceeded.
IOException- An I/O error occurred.
Move(int, int)
ImageCollection.csMoves an entry to another index, shifting the entries in between.
RemoveAt(int)
ImageCollection.csRemoves an entry. An entry that owns a copied image releases it.
Parameters
indexint- The zero-based index.
Exceptions
ArgumentOutOfRangeException- The index is outside the collection.
Save overloads
Save(Stream, ImageEncoder)
ImageCollection.csEncodes the collection to a stream, starting at its current position. The stream is left open.
public void Save(Stream stream, ImageEncoder encoder)Parameters
streamStream- The writable destination. TIFF output also requires a seekable stream (the directory offsets are patched once the pages are written).
encoderImageEncoder- The encoder.
Exceptions
ArgumentExceptionstreamis not writable, is not seekable when the output requires it, or the encoder does not produce a multi-entry format.InvalidOperationException- The collection is empty.
UnsupportedImageFeatureException- An entry cannot be encoded without a loss the encoder settings do not allow.
Save(string, ImageEncoder?)
ImageCollection.csEncodes the collection to a file, published atomically.
public void Save(string path, ImageEncoder? encoder = null)Parameters
pathstring- The destination path.
encoderImageEncoder?- The encoder, or
nullto select it from the extension (.tif,.tiff,.ico,.cur).
Exceptions
ArgumentExceptionpathis empty, or the extension does not select a multi-entry encoder.InvalidOperationException- The collection is empty.
UnsupportedImageFeatureException- An entry cannot be encoded without a loss the encoder settings do not allow.
IOException- An I/O error occurred.
SaveAsync overloads
SaveAsync(Stream, ImageEncoder, CancellationToken)
ImageCollection.csAsynchronously encodes the collection to a stream, starting at its current position. The stream is left open.
public Task SaveAsync(Stream stream, ImageEncoder encoder, CancellationToken cancellationToken = default)Parameters
streamStream- The writable destination. TIFF output also requires a seekable stream (the directory offsets are patched once the pages are written).
encoderImageEncoder- The encoder.
cancellationTokenCancellationToken- The token to monitor for cancellation requests.
Returns
Task A task that completes when the collection has been written and the stream flushed.
Exceptions
ArgumentExceptionstreamis not writable, is not seekable when the output requires it, or the encoder does not produce a multi-entry format.InvalidOperationException- The collection is empty.
UnsupportedImageFeatureException- An entry cannot be encoded without a loss the encoder settings do not allow.
OperationCanceledException- The operation was canceled.
Remarks
The arguments, the encoder and the collection are validated before the method returns. The stream is written with Stream.WriteAsync; the entries are encoded synchronously between the writes, one entry at a time. On failure or cancellation, the bytes already written stay in the stream: its content is then not a valid file. The save must not overlap any other call on the collection until the task completes.
SaveAsync(string, ImageEncoder?, CancellationToken)
ImageCollection.csAsynchronously encodes the collection to a file, with the same atomic-publication guarantees as ImageCollection.Save.
public Task SaveAsync(string path, ImageEncoder? encoder = null, CancellationToken cancellationToken = default)Parameters
pathstring- The destination path.
encoderImageEncoder?- The encoder, or
nullto select it from the extension (.tif,.tiff,.ico,.cur). cancellationTokenCancellationToken- The token to monitor for cancellation requests. On cancellation, no file is published.
Returns
Task A task that completes when the file has been published.
Exceptions
ArgumentExceptionpathis empty, or the extension does not select a multi-entry encoder.InvalidOperationException- The collection is empty.
UnsupportedImageFeatureException- An entry cannot be encoded without a loss the encoder settings do not allow.
IOException- An I/O error occurred.
OperationCanceledException- The operation was canceled.
Remarks
The arguments, the encoder and the collection are validated before the method returns, as by ImageCollection.Save. The file is written with asynchronous I/O; the entries are encoded, and the entries backed by the encoded input are read and decoded, synchronously between the writes, one entry at a time. The token is checked before the file is created, before each entry, between the strips of a TIFF page and by every write. A failure or a cancellation deletes the temporary file and leaves an existing destination unchanged.
Like ImageCollection.Save, the save must not overlap any other call on the collection until the task completes.
SelectBySize(Size)
ImageCollection.csSelects the representation that best matches a requested size: the smallest entry at least as large as size in both directions, or, when none is large enough, the largest entry. Ties are broken by the highest stored bit depth, then by container order.
public ImageCollectionEntry SelectBySize(Size size)Parameters
sizeSize- The requested size, in pixels.
Returns
ImageCollectionEntry The selected entry. Nothing is decoded or resized.
Exceptions
ArgumentOutOfRangeException- A dimension is not positive.
InvalidOperationException- The collection is empty.