Class YuvRaster
- Namespace
- Egami
- Assembly
- Egami.dll
A picture held as separate luma (Y) and chroma (U, V) planes, plus an optional alpha plane, the way video codecs, AVIF, lossy WebP and JPEG store it. This base class is used when the sample type is not known at compile time; YuvRaster<TSample> gives the planes. Convert to and from a Raster with ToRaster(YuvConvertOptions?), CopyTo<TPixel>(Raster<TPixel>, YuvConvertOptions?, CancellationToken) and FromRaster(Raster, ChromaFormat, YuvColor, bool, YuvConvertOptions?).
public abstract class YuvRaster : IDisposable
- Inheritance
-
YuvRaster
- Implements
- Derived
-
YuvRaster<TSample>
- Inherited Members
Examples
// A 1080p frame as video stores it: full-size luma, chroma at half width and height, BT.709 at limited range.
using YuvRaster<byte> frame = YuvRaster.Create(1920, 1080, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
// 10-bit HDR planes hold samples 0 to 1023 in ushorts; an alpha plane is optional.
using YuvRaster<ushort> hdr = YuvRaster.Create(3840, 2160, ChromaFormat.Yuv420, 10, YuvColor.Bt2020Limited, alpha: true);
Console.WriteLine($"Chroma planes are {frame.U!.Width}×{frame.U.Height}");
Remarks
A YUV raster is not a Raster: one pixel is spread over planes of different sizes. Operations other than
Crop and Resize run on a Raster after conversion. It is not thread-safe for writing, like a raster.
Properties
BitDepth
public int BitDepth { get; }
Property Value
ChromaFormat
Gets the chroma resolution against luma.
public ChromaFormat ChromaFormat { get; }
Property Value
Color
Gets how the samples turn into RGB: matrix, range and chroma siting.
public YuvColor Color { get; }
Property Value
HasAlpha
Gets a value indicating whether the raster has an alpha plane.
public abstract bool HasAlpha { get; }
Property Value
Height
Gets the height of the luma plane in pixels.
public int Height { get; }
Property Value
Metadata
Gets the metadata (EXIF, ICC, XMP and the rest), carried to and from a Raster on conversion.
public RasterMetadata Metadata { get; }
Property Value
Width
Gets the width of the luma plane in pixels.
public int Width { get; }
Property Value
Methods
CopyFromPacked(YuvPackedFormat, ReadOnlySpan<byte>, int, ReadOnlySpan<byte>, int)
Copies a frame in an interleaved layout into this raster's planes, with one SIMD pass. The raster must match the layout: 4:2:0 8-bit for NV12 and NV21, 4:2:0 10-bit for P010, 4:2:0 at 10, 12 or 16 bits for P016, 4:2:2 8-bit for YUYV and UYVY.
public void CopyFromPacked(YuvPackedFormat format, ReadOnlySpan<byte> data, int stride = 0, ReadOnlySpan<byte> chroma = default, int chromaStride = 0)
Parameters
formatYuvPackedFormatThe layout.
dataReadOnlySpan<byte>The frame: the luma plane for two-plane layouts, or the only plane for packed 4:2:2.
strideintThe distance between rows of
data, in bytes. 0 means rows are packed.chromaReadOnlySpan<byte>The interleaved chroma plane of a two-plane layout, or empty when it follows the luma rows in
data(atstride× Height). Ignored for YUYV and UYVY.chromaStrideintThe distance between chroma rows, in bytes. 0 means the luma stride, or the packed chroma row when an odd width makes that longer.
Examples
// An NV12 frame from Media Foundation or MediaCodec: Y rows, then interleaved U, V rows, both at the same stride.
int width = 640, height = 360, stride = 704;
byte[] nv12 = new byte[stride * height * 3 / 2];
using YuvRaster<byte> frame = YuvRaster.Create(width, height, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
frame.CopyFromPacked(YuvPackedFormat.Nv12, nv12, stride);
// A webcam's YUYV, 4:2:2 in one plane, the other way.
using YuvRaster<byte> webcam = YuvRaster.Create(width, height, ChromaFormat.Yuv422, YuvColor.Bt601Limited);
byte[] yuyv = new byte[width * 2 * height];
webcam.CopyToPacked(YuvPackedFormat.Yuyv, yuyv);
Exceptions
- ArgumentException
The raster does not match the layout.
- ArgumentOutOfRangeException
A stride is too small or a span too short.
- ObjectDisposedException
The raster has been disposed.
CopyFrom<TPixel>(Raster<TPixel>, YuvConvertOptions?, CancellationToken)
Converts the first frame of a raster of the same size into this one, with no allocation after the first call. The alpha plane, if any, takes the source's alpha (opaque for sources without). This raster's metadata is left alone.
public void CopyFrom<TPixel>(Raster<TPixel> source, YuvConvertOptions? options = null, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
sourceRaster<TPixel>The raster to read.
optionsYuvConvertOptionscancellationTokenCancellationTokenCancels between bands of rows.
Type Parameters
TPixelThe source's pixel type.
Examples
// A player converts every frame into the same raster: after the first frame, nothing is allocated.
using YuvRaster<byte> frame = YuvRaster.Create(1280, 720, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster<Bgra8> screen = Raster.Create<Bgra8>(1280, 720);
for (int i = 0; i < 3; i++)
{
// ... the decoder writes frame's planes ...
frame.CopyTo(screen);
}
// And the other way, for an encoder: CopyFrom fills existing planes.
frame.CopyFrom(screen);
Exceptions
- ArgumentNullException
sourceis null.- ArgumentException
The source is not the same size.
- ObjectDisposedException
Either raster has been disposed.
- OperationCanceledException
cancellationTokenwas canceled.
CopyToPacked(YuvPackedFormat, Span<byte>, int, Span<byte>, int)
Copies this raster's planes into a frame in an interleaved layout, with one SIMD pass. See CopyFromPacked(YuvPackedFormat, ReadOnlySpan<byte>, int, ReadOnlySpan<byte>, int) for the layouts each raster matches.
public void CopyToPacked(YuvPackedFormat format, Span<byte> data, int stride = 0, Span<byte> chroma = default, int chromaStride = 0)
Parameters
formatYuvPackedFormatThe layout.
dataSpan<byte>The frame: the luma plane for two-plane layouts, or the only plane for packed 4:2:2.
strideintThe distance between rows of
data, in bytes. 0 means rows are packed.chromaSpan<byte>The interleaved chroma plane of a two-plane layout, or empty to write it after the luma rows in
data(atstride× Height). Ignored for YUYV and UYVY.chromaStrideintThe distance between chroma rows, in bytes. 0 means the luma stride, or the packed chroma row when an odd width makes that longer.
Exceptions
- ArgumentException
The raster does not match the layout.
- ArgumentOutOfRangeException
A stride is too small or a span too short.
- ObjectDisposedException
The raster has been disposed.
CopyTo<TPixel>(Raster<TPixel>, YuvConvertOptions?, CancellationToken)
Converts into the first frame of an existing raster of the same size, with no allocation after the first call, so a video can reuse one raster for every frame. The target's metadata is left alone.
public void CopyTo<TPixel>(Raster<TPixel> target, YuvConvertOptions? options = null, CancellationToken cancellationToken = default) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
targetRaster<TPixel>The raster to write.
optionsYuvConvertOptionscancellationTokenCancellationTokenCancels between bands of rows.
Type Parameters
TPixelThe target's pixel type.
Examples
// A player converts every frame into the same raster: after the first frame, nothing is allocated.
using YuvRaster<byte> frame = YuvRaster.Create(1280, 720, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster<Bgra8> screen = Raster.Create<Bgra8>(1280, 720);
for (int i = 0; i < 3; i++)
{
// ... the decoder writes frame's planes ...
frame.CopyTo(screen);
}
// And the other way, for an encoder: CopyFrom fills existing planes.
frame.CopyFrom(screen);
Exceptions
- ArgumentNullException
targetis null.- ArgumentException
The target is not the same size.
- ObjectDisposedException
Either raster has been disposed.
- OperationCanceledException
cancellationTokenwas canceled.
Create(int, int, ChromaFormat, YuvColor, bool, EgamiContext?)
Creates an 8-bit raster with every sample zero.
public static YuvRaster<byte> Create(int width, int height, ChromaFormat chromaFormat, YuvColor color, bool alpha = false, EgamiContext? context = null)
Parameters
widthintThe luma width in pixels, at least 1.
heightintThe luma height in pixels, at least 1.
chromaFormatChromaFormatThe chroma resolution.
colorYuvColorHow the samples turn into RGB.
alphaboolWhether to add a full-size alpha plane.
contextEgamiContext
Returns
Exceptions
- ArgumentOutOfRangeException
A size is less than 1, or an enum value is undefined.
- LimitExceededException
The size or memory breaks the context's SafetyLimits.
Create(int, int, ChromaFormat, int, YuvColor, bool, EgamiContext?)
Creates a 10-, 12- or 16-bit raster with every sample zero.
public static YuvRaster<ushort> Create(int width, int height, ChromaFormat chromaFormat, int bitDepth, YuvColor color, bool alpha = false, EgamiContext? context = null)
Parameters
widthintThe luma width in pixels, at least 1.
heightintThe luma height in pixels, at least 1.
chromaFormatChromaFormatThe chroma resolution.
bitDepthintThe bits per sample: 10, 12 or 16.
colorYuvColorHow the samples turn into RGB.
alphaboolWhether to add a full-size alpha plane.
contextEgamiContext
Returns
Exceptions
- ArgumentOutOfRangeException
A size is less than 1, the bit depth is not 10, 12 or 16, or an enum value is undefined.
- LimitExceededException
The size or memory breaks the context's SafetyLimits.
Crop(Rect)
Returns a new raster holding rect of this one. The rectangle's corner must fall on a chroma sample: even
x and y for 4:2:0, even x for 4:2:2, x a multiple of 4 for 4:1:1, and x and y multiples of 4 for 4:1:0. Chroma is copied
exactly, with no filtering.
public YuvRaster Crop(Rect rect)
Parameters
rectRectThe area to keep, in luma pixels.
Returns
- YuvRaster
The new raster, with a copy of the metadata. The caller must dispose it.
Examples
using YuvRaster<byte> frame = YuvRaster.Create(1920, 1080, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
// Scale the planes before converting, as video does; crops start on a chroma sample (even x and y at 4:2:0).
using YuvRaster<byte> small = frame.Resize(1280, 720, ResampleFilter.Bicubic);
using YuvRaster<byte> center = small.Crop(new Rect(320, 180, 640, 360));
// A player scales every frame into the same raster.
using YuvRaster<byte> screen = YuvRaster.Create(960, 540, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
frame.ResizeTo(screen);
// Everything else (rotate, color adjustments, drawing) runs on a Raster after conversion.
using Raster<Rgba8> rgb = center.ToRaster<Rgba8>();
rgb.Apply(ops => ops.Rotate(90));
Exceptions
- ArgumentOutOfRangeException
The rectangle is empty or reaches outside the raster.
- ArgumentException
The rectangle's corner is not on a chroma sample.
- ObjectDisposedException
The raster has been disposed.
Dispose()
Returns the planes' memory to its source, or disposes the owner of wrapped planes. Calling it again does nothing.
public void Dispose()
FromRaster(Raster, ChromaFormat, YuvColor, bool, YuvConvertOptions?)
Converts the first frame of a raster to a new 8-bit YUV raster. Metadata is copied.
public static YuvRaster<byte> FromRaster(Raster source, ChromaFormat chromaFormat, YuvColor color, bool alpha = false, YuvConvertOptions? options = null)
Parameters
sourceRasterThe raster to convert, of any pixel type.
chromaFormatChromaFormatThe chroma resolution.
colorYuvColorThe matrix, range and siting to encode with.
alphaboolWhether to add an alpha plane, holding the source's alpha (opaque for sources without). Defaults to false: alpha is dropped.
optionsYuvConvertOptions
Returns
Examples
using Raster photo = Raster.Load("duck.png");
// RGB to planes and back. RGB comes out in the picture's own transfer (BT.709 video gives BT.709-encoded RGB).
using YuvRaster<byte> yuv = YuvRaster.FromRaster(photo, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster rgba = yuv.ToRaster(); // Rgba8 for 8-bit planes, Rgba16 for more
using Raster<Rgb8> rgb = yuv.ToRaster<Rgb8>(); // or any pixel type
Exceptions
- ArgumentNullException
sourceis null.- ObjectDisposedException
sourcehas been disposed.
FromRaster(Raster, ChromaFormat, int, YuvColor, bool, YuvConvertOptions?)
Converts the first frame of a raster to a new 10-, 12- or 16-bit YUV raster. Metadata is copied.
public static YuvRaster<ushort> FromRaster(Raster source, ChromaFormat chromaFormat, int bitDepth, YuvColor color, bool alpha = false, YuvConvertOptions? options = null)
Parameters
sourceRasterThe raster to convert, of any pixel type.
chromaFormatChromaFormatThe chroma resolution.
bitDepthintThe bits per sample: 10, 12 or 16.
colorYuvColorThe matrix, range and siting to encode with.
alphaboolWhether to add an alpha plane, holding the source's alpha (opaque for sources without). Defaults to false: alpha is dropped.
optionsYuvConvertOptions
Returns
Examples
using Raster photo = Raster.Load("duck.png");
// RGB to planes and back. RGB comes out in the picture's own transfer (BT.709 video gives BT.709-encoded RGB).
using YuvRaster<byte> yuv = YuvRaster.FromRaster(photo, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster rgba = yuv.ToRaster(); // Rgba8 for 8-bit planes, Rgba16 for more
using Raster<Rgb8> rgb = yuv.ToRaster<Rgb8>(); // or any pixel type
Exceptions
- ArgumentNullException
sourceis null.- ArgumentOutOfRangeException
The bit depth is not 10, 12 or 16.
- ObjectDisposedException
sourcehas been disposed.
Load(Stream, EgamiContext?, ReaderOptions?)
Decodes a format's own planes, with no color conversion or chroma upsampling: for JPEG, a YCbCr file's planes at its own sampling (4:2:0, 4:2:2 or 4:4:4; other samplings are replicated up to 4:4:4) and a gray file's as 4:0:0, all Jpeg. MinimumSize decodes at a reduced scale (1/2, 1/4 or 1/8).
public static YuvRaster Load(Stream stream, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
streamStreamThe encoded image. It is read from its current position and left open.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRaster
The raster. The caller must dispose it.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- NotSupportedException
The format, or this file (a CMYK, YCCK or RGB JPEG), has no YUV planes; Load(Stream, EgamiContext?, ReaderOptions?) converts it. Also thrown for Region and ConvertColorTo.
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The data breaks the format's rules.
- LimitExceededException
The image breaks a safety limit.
- ArgumentNullException
streamis null.
Load(ReadOnlyMemory<byte>, EgamiContext?, ReaderOptions?)
Loads an image's planes from bytes in memory. See Load(Stream, EgamiContext?, ReaderOptions?).
public static YuvRaster Load(ReadOnlyMemory<byte> data, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
dataReadOnlyMemory<byte>The encoded image.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRaster
The raster. The caller must dispose it.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- NotSupportedException
The format or file has no YUV planes.
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The data breaks the format's rules.
- LimitExceededException
The image breaks a safety limit.
Load(string, EgamiContext?, ReaderOptions?)
Loads an image file's planes. See Load(Stream, EgamiContext?, ReaderOptions?).
public static YuvRaster Load(string path, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
pathstringThe file path.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRaster
The raster. The caller must dispose it.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- NotSupportedException
The format or file has no YUV planes.
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The data breaks the format's rules.
- LimitExceededException
The image breaks a safety limit.
- FileNotFoundException
The file does not exist.
Probe(Stream, EgamiContext?, ReaderOptions?)
Reads only the header, as Probe(Stream, EgamiContext?, ReaderOptions?) does, and says whether Load(Stream, EgamiContext?, ReaderOptions?) would give planes and in what chroma format.
public static YuvRasterInfo Probe(Stream stream, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
streamStreamThe encoded image.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRasterInfo
What the header says.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The header breaks the format's rules.
- ArgumentNullException
streamis null.
Probe(ReadOnlyMemory<byte>, EgamiContext?, ReaderOptions?)
Reads only the header of an image in memory. See Probe(Stream, EgamiContext?, ReaderOptions?).
public static YuvRasterInfo Probe(ReadOnlyMemory<byte> data, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
dataReadOnlyMemory<byte>The encoded image.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRasterInfo
What the header says.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The header breaks the format's rules.
Probe(string, EgamiContext?, ReaderOptions?)
Reads only the header of an image file. See Probe(Stream, EgamiContext?, ReaderOptions?).
public static YuvRasterInfo Probe(string path, EgamiContext? context = null, ReaderOptions? options = null)
Parameters
pathstringThe file path.
contextEgamiContextoptionsReaderOptions
Returns
- YuvRasterInfo
What the header says.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
No registered format matches the data.
- CorruptDataException
The header breaks the format's rules.
- FileNotFoundException
The file does not exist.
Resize(int, int, ResampleFilter)
Returns a new raster with every plane resized by filter, as a Gray8 or Gray16
resize would, keeping the chroma format, siting and color. Samples are clamped to the bit depth, since some filters
overshoot. Scaling planes before converting costs half as much at 4:2:0 as scaling RGB after.
public YuvRaster Resize(int width, int height, ResampleFilter filter = ResampleFilter.Bicubic)
Parameters
widthintThe new luma width, at least 1.
heightintThe new luma height, at least 1.
filterResampleFilterThe resampling kernel. Defaults to Bicubic.
Returns
- YuvRaster
The new raster, with a copy of the metadata. The caller must dispose it.
Examples
using YuvRaster<byte> frame = YuvRaster.Create(1920, 1080, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
// Scale the planes before converting, as video does; crops start on a chroma sample (even x and y at 4:2:0).
using YuvRaster<byte> small = frame.Resize(1280, 720, ResampleFilter.Bicubic);
using YuvRaster<byte> center = small.Crop(new Rect(320, 180, 640, 360));
// A player scales every frame into the same raster.
using YuvRaster<byte> screen = YuvRaster.Create(960, 540, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
frame.ResizeTo(screen);
// Everything else (rotate, color adjustments, drawing) runs on a Raster after conversion.
using Raster<Rgba8> rgb = center.ToRaster<Rgba8>();
rgb.Apply(ops => ops.Rotate(90));
Exceptions
- ArgumentOutOfRangeException
A size is less than 1.
- LimitExceededException
The new raster breaks the context's SafetyLimits.
- ObjectDisposedException
The raster has been disposed.
ResizeTo(YuvRaster, ResampleFilter)
Resizes every plane into an existing raster of the size wanted, as Resize(int, int, ResampleFilter) does, so a video can scale every frame into the same raster. The target must have the same sample type, chroma format, bit depth and color. An alpha plane is resized when both have one; a target alpha plane with no source alpha is made opaque. The target's metadata is left alone.
public void ResizeTo(YuvRaster target, ResampleFilter filter = ResampleFilter.Bicubic)
Parameters
targetYuvRasterThe raster to write, of any size.
filterResampleFilterThe resampling kernel. Defaults to Bicubic.
Examples
using YuvRaster<byte> frame = YuvRaster.Create(1920, 1080, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
// Scale the planes before converting, as video does; crops start on a chroma sample (even x and y at 4:2:0).
using YuvRaster<byte> small = frame.Resize(1280, 720, ResampleFilter.Bicubic);
using YuvRaster<byte> center = small.Crop(new Rect(320, 180, 640, 360));
// A player scales every frame into the same raster.
using YuvRaster<byte> screen = YuvRaster.Create(960, 540, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
frame.ResizeTo(screen);
// Everything else (rotate, color adjustments, drawing) runs on a Raster after conversion.
using Raster<Rgba8> rgb = center.ToRaster<Rgba8>();
rgb.Apply(ops => ops.Rotate(90));
Exceptions
- ArgumentNullException
targetis null.- ArgumentException
The target is this raster, or differs in sample type, chroma format, bit depth or color.
- ObjectDisposedException
Either raster has been disposed.
Save(Stream, FormatInfo, WriterOptions?)
Encodes the picture in format. JPEG encodes the planes straight, with no color conversion or chroma
downsampling, when they are 8-bit BT.601 at full range (4:2:0, 4:2:2 and 4:4:4 keep their sampling, 4:0:0 is gray); other
planes are converted to that first, 4:1:1 to 4:2:2 and 4:1:0 to 4:2:0. AVIF encodes planes of 8, 10 or 12 bits straight,
their matrix, range and chroma siting written into the file, and alpha as an alpha item; AV1 has no 4:1:1 or 4:1:0, so those
are saved from RGB. Other formats are saved from
ToRaster(YuvConvertOptions?).
public void Save(Stream stream, FormatInfo format, WriterOptions? options = null)
Parameters
streamStreamWhere to write, from its current position. It is left open.
formatFormatInfoThe format.
optionsWriterOptionsThe format's options, or null for its defaults. JPEG's subsampling comes from the planes.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
The format has no writer.
- ObjectDisposedException
The raster has been disposed.
- ArgumentNullException
streamorformatis null.
Save(Stream, string, WriterOptions?)
Encodes the picture in the registered format with this name or file extension. See Save(Stream, FormatInfo, WriterOptions?).
public void Save(Stream stream, string formatNameOrExtension, WriterOptions? options = null)
Parameters
streamStreamWhere to write, from its current position. It is left open.
formatNameOrExtensionstringThe format's name or one of its extensions, ignoring case.
optionsWriterOptionsThe format's options, or null for its defaults.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
No registered format matches, or it has no writer.
- ObjectDisposedException
The raster has been disposed.
Save(string, WriterOptions?)
Encodes the picture to a file, choosing the format from the extension. An existing file is replaced; if encoding fails, the partly written file is deleted. See Save(Stream, FormatInfo, WriterOptions?).
public void Save(string path, WriterOptions? options = null)
Parameters
pathstringThe file path.
optionsWriterOptionsThe format's options, or null for its defaults.
Examples
// A JPEG's own planes, as decoded: no chroma upsampling and no color conversion.
YuvRasterInfo info = YuvRaster.Probe("duck.jpg");
Console.WriteLine($"{info.Info.Width}×{info.Info.Height}, planes: {info.ChromaFormat}");
using YuvRaster planes = YuvRaster.Load("duck.jpg");
// Saving JPEG-colored 8-bit planes skips color conversion and downsampling; other planes are converted first.
planes.Save("copy.jpg", new JpegWriterOptions { Quality = 90 });
Exceptions
- UnsupportedFormatException
No registered format uses the extension, or it has no writer.
- ObjectDisposedException
The raster has been disposed.
- IOException
The file cannot be written.
ToRaster(YuvConvertOptions?)
Converts to a new raster in the natural pixel type: Rgba8 for 8-bit samples, Rgba16 for more. RGB comes out in the picture's own transfer function; nothing is linearized or tone mapped.
public Raster ToRaster(YuvConvertOptions? options = null)
Parameters
optionsYuvConvertOptions
Returns
- Raster
The new raster, with a copy of the metadata. The caller must dispose it.
Examples
using Raster photo = Raster.Load("duck.png");
// RGB to planes and back. RGB comes out in the picture's own transfer (BT.709 video gives BT.709-encoded RGB).
using YuvRaster<byte> yuv = YuvRaster.FromRaster(photo, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster rgba = yuv.ToRaster(); // Rgba8 for 8-bit planes, Rgba16 for more
using Raster<Rgb8> rgb = yuv.ToRaster<Rgb8>(); // or any pixel type
Exceptions
- ObjectDisposedException
The raster has been disposed.
ToRaster<TPixel>(YuvConvertOptions?)
Converts to a new raster of TPixel. See ToRaster(YuvConvertOptions?).
public Raster<TPixel> ToRaster<TPixel>(YuvConvertOptions? options = null) where TPixel : unmanaged, IPixelType<TPixel>
Parameters
optionsYuvConvertOptions
Returns
- Raster<TPixel>
The new raster, with a copy of the metadata. The caller must dispose it.
Type Parameters
TPixelThe pixel type.
Examples
using Raster photo = Raster.Load("duck.png");
// RGB to planes and back. RGB comes out in the picture's own transfer (BT.709 video gives BT.709-encoded RGB).
using YuvRaster<byte> yuv = YuvRaster.FromRaster(photo, ChromaFormat.Yuv420, YuvColor.Bt709Limited);
using Raster rgba = yuv.ToRaster(); // Rgba8 for 8-bit planes, Rgba16 for more
using Raster<Rgb8> rgb = yuv.ToRaster<Rgb8>(); // or any pixel type
Exceptions
- ObjectDisposedException
The raster has been disposed.
- LimitExceededException
The new raster breaks the context's MaxTotalBytes.
Wrap<TSample>(Memory<TSample>, int, Memory<TSample>, int, Memory<TSample>, int, int, int, ChromaFormat, int, YuvColor, IDisposable?, EgamiContext?)
Creates a raster over planes the caller owns, such as a decoder's or the operating system's frame buffers, without copying.
When owner is given, disposing the raster disposes it; otherwise the caller keeps the memory alive while
the raster is used. Sizes and strides are checked up front; SafetyLimits do not apply to wrapped memory.
public static YuvRaster<TSample> Wrap<TSample>(Memory<TSample> y, int yStride, Memory<TSample> u, int uStride, Memory<TSample> v, int vStride, int width, int height, ChromaFormat chromaFormat, int bitDepth, YuvColor color, IDisposable? owner = null, EgamiContext? context = null) where TSample : unmanaged
Parameters
yMemory<TSample>The luma plane.
yStrideintThe distance between luma rows, in samples. 0 means rows are packed.
uMemory<TSample>The U (Cb) plane, or empty for 4:0:0.
uStrideintThe distance between U rows, in samples. 0 means rows are packed.
vMemory<TSample>The V (Cr) plane, or empty for 4:0:0.
vStrideintThe distance between V rows, in samples. 0 means rows are packed.
widthintThe luma width in pixels, at least 1.
heightintThe luma height in pixels, at least 1.
chromaFormatChromaFormatThe chroma resolution.
bitDepthintThe bits per sample: 8 for bytes; 10, 12 or 16 for ushort.
colorYuvColorHow the samples turn into RGB.
ownerIDisposableWhat to dispose with the raster, or null.
contextEgamiContext
Returns
- YuvRaster<TSample>
The raster.
Type Parameters
Examples
// A decoder's 10-bit frame, rows padded to 64 samples: wrapped without a copy. Disposing the raster disposes the owner.
int width = 50, height = 30, stride = 64, chromaStride = 32;
ushort[] y = new ushort[stride * height], u = new ushort[chromaStride * 15], v = new ushort[chromaStride * 15];
using YuvRaster<ushort> wrapped = YuvRaster.Wrap<ushort>(
y, stride, u, chromaStride, v, chromaStride, width, height, ChromaFormat.Yuv420, bitDepth: 10, YuvColor.Bt2020Limited, owner: null);
Exceptions
- ArgumentOutOfRangeException
A size, stride or bit depth is out of range, or a plane is too short.
- ArgumentException
Chroma planes are given for 4:0:0, or missing for another format.
- NotSupportedException
Wrap<TSample>(Memory<TSample>, int, Memory<TSample>, int, Memory<TSample>, int, Memory<TSample>, int, int, int, ChromaFormat, int, YuvColor, IDisposable?, EgamiContext?)
Creates a raster over planes the caller owns, with an alpha plane, without copying. See Wrap<TSample>(Memory<TSample>, int, Memory<TSample>, int, Memory<TSample>, int, int, int, ChromaFormat, int, YuvColor, IDisposable?, EgamiContext?).
public static YuvRaster<TSample> Wrap<TSample>(Memory<TSample> y, int yStride, Memory<TSample> u, int uStride, Memory<TSample> v, int vStride, Memory<TSample> alpha, int alphaStride, int width, int height, ChromaFormat chromaFormat, int bitDepth, YuvColor color, IDisposable? owner = null, EgamiContext? context = null) where TSample : unmanaged
Parameters
yMemory<TSample>The luma plane.
yStrideintThe distance between luma rows, in samples. 0 means rows are packed.
uMemory<TSample>The U (Cb) plane, or empty for 4:0:0.
uStrideintThe distance between U rows, in samples. 0 means rows are packed.
vMemory<TSample>The V (Cr) plane, or empty for 4:0:0.
vStrideintThe distance between V rows, in samples. 0 means rows are packed.
alphaMemory<TSample>The full-size alpha plane, straight (not premultiplied), at the same bit depth.
alphaStrideintThe distance between alpha rows, in samples. 0 means rows are packed.
widthintThe luma width in pixels, at least 1.
heightintThe luma height in pixels, at least 1.
chromaFormatChromaFormatThe chroma resolution.
bitDepthintThe bits per sample: 8 for bytes; 10, 12 or 16 for ushort.
colorYuvColorHow the samples turn into RGB.
ownerIDisposableWhat to dispose with the raster, or null.
contextEgamiContext
Returns
- YuvRaster<TSample>
The raster.
Type Parameters
Exceptions
- ArgumentOutOfRangeException
A size, stride or bit depth is out of range, or a plane is too short.
- ArgumentException
Chroma planes are given for 4:0:0, or missing for another format.
- NotSupportedException