Class JxlImage
Reads what JPEG XL holds besides the image Load gives: the layers before blending, and the preview.
public static class JxlImage
- Inheritance
-
JxlImage
- Inherited Members
Examples
// An animation loads as its frames, blended onto the canvas, each with its delay.
using Raster animation = Raster.Load("sprite.jxl");
int frames = animation.FrameCount;
// The layers before blending, for an editor: each at its own size and place.
IReadOnlyList<JxlLayer> layers = JxlImage.ReadLayers("sprite.jxl");
foreach (JxlLayer layer in layers)
{
Console.WriteLine($"{layer.Raster.Width}x{layer.Raster.Height} at {layer.X},{layer.Y}: {layer.Blend}, {layer.Duration.TotalMilliseconds} ms");
layer.Dispose();
}
// The preview some files carry for quick display, or null.
using Raster? preview = JxlImage.ReadPreview("duck.jxl");
// A lossy still at an eighth of its size, from its LF image alone.
using Raster thumbnail = Raster.Load("duck.jxl", options: new JxlReaderOptions { MaxDownscale = 8 });
Methods
ReadExtraChannel(Stream, int, ReaderOptions?, EgamiContext?)
Reads one extra channel from a stream; see ReadExtraChannel(string, int, ReaderOptions?, EgamiContext?).
public static Raster<GrayF32> ReadExtraChannel(Stream stream, int index, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
streamStreamThe file's data, from its start.
indexintThe channel's index in ExtraChannels.
optionsReaderOptionsThe general options, with the frame range.
contextEgamiContext
Returns
Examples
// Alpha joins the pixels (straight, even when the file premultiplies); other extra channels are listed in the details.
using Raster image = Raster.Load("sprite.jxl");
JxlDetails details = (JxlDetails)image.Metadata.FormatDetails!;
foreach (JxlExtraChannel channel in details.ExtraChannels)
{
Console.WriteLine($"{channel.Kind} '{channel.Name}', {channel.BitsPerSample} bits");
}
// Any one of them alone, such as depth or a selection mask, as gray floats.
using Raster<GrayF32> alpha = JxlImage.ReadExtraChannel("sprite.jxl", 0);
// Spot colors are mixed into the color as djxl does, unless turned off.
using Raster plain = Raster.Load("sprite.jxl", options: new JxlReaderOptions { RenderSpotColors = false });
Exceptions
- ArgumentOutOfRangeException
The image has no extra channel
index.- CorruptDataException
The data breaks the format's rules, including data of another format.
ReadExtraChannel(string, int, ReaderOptions?, EgamiContext?)
Reads one extra channel, such as depth, a selection mask, thermal data or a spot color, into a gray raster at the image size: as stored, scaled to 0 to 1 for integer samples, with a frame for each frame Load shows.
public static Raster<GrayF32> ReadExtraChannel(string path, int index, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
pathstringThe file.
indexintThe channel's index in ExtraChannels.
optionsReaderOptionsThe general options, with the frame range.
contextEgamiContext
Returns
Examples
// Alpha joins the pixels (straight, even when the file premultiplies); other extra channels are listed in the details.
using Raster image = Raster.Load("sprite.jxl");
JxlDetails details = (JxlDetails)image.Metadata.FormatDetails!;
foreach (JxlExtraChannel channel in details.ExtraChannels)
{
Console.WriteLine($"{channel.Kind} '{channel.Name}', {channel.BitsPerSample} bits");
}
// Any one of them alone, such as depth or a selection mask, as gray floats.
using Raster<GrayF32> alpha = JxlImage.ReadExtraChannel("sprite.jxl", 0);
// Spot colors are mixed into the color as djxl does, unless turned off.
using Raster plain = Raster.Load("sprite.jxl", options: new JxlReaderOptions { RenderSpotColors = false });
Exceptions
- ArgumentOutOfRangeException
The image has no extra channel
index.- CorruptDataException
The data breaks the format's rules, including data of another format.
ReadLayers(Stream, ReaderOptions?, EgamiContext?)
Reads every regular frame before blending from a stream; see ReadLayers(string, ReaderOptions?, EgamiContext?).
public static IReadOnlyList<JxlLayer> ReadLayers(Stream stream, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
streamStreamThe file's data, from its start.
optionsReaderOptionsThe general options; the frame range is ignored.
contextEgamiContext
Returns
- IReadOnlyList<JxlLayer>
The layers, in the file's order. The caller must dispose each.
Examples
// An animation loads as its frames, blended onto the canvas, each with its delay.
using Raster animation = Raster.Load("sprite.jxl");
int frames = animation.FrameCount;
// The layers before blending, for an editor: each at its own size and place.
IReadOnlyList<JxlLayer> layers = JxlImage.ReadLayers("sprite.jxl");
foreach (JxlLayer layer in layers)
{
Console.WriteLine($"{layer.Raster.Width}x{layer.Raster.Height} at {layer.X},{layer.Y}: {layer.Blend}, {layer.Duration.TotalMilliseconds} ms");
layer.Dispose();
}
// The preview some files carry for quick display, or null.
using Raster? preview = JxlImage.ReadPreview("duck.jxl");
// A lossy still at an eighth of its size, from its LF image alone.
using Raster thumbnail = Raster.Load("duck.jxl", options: new JxlReaderOptions { MaxDownscale = 8 });
Exceptions
- CorruptDataException
The data breaks the format's rules, including data of another format.
ReadLayers(string, ReaderOptions?, EgamiContext?)
Reads every regular frame as it is before blending, for editors: each in the file's color space and natural pixel type, at its own size, with where it goes on the canvas and how it blends. Load gives the frames already blended.
public static IReadOnlyList<JxlLayer> ReadLayers(string path, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
pathstringThe file.
optionsReaderOptionsThe general options; the frame range is ignored.
contextEgamiContext
Returns
- IReadOnlyList<JxlLayer>
The layers, in the file's order. The caller must dispose each.
Examples
// An animation loads as its frames, blended onto the canvas, each with its delay.
using Raster animation = Raster.Load("sprite.jxl");
int frames = animation.FrameCount;
// The layers before blending, for an editor: each at its own size and place.
IReadOnlyList<JxlLayer> layers = JxlImage.ReadLayers("sprite.jxl");
foreach (JxlLayer layer in layers)
{
Console.WriteLine($"{layer.Raster.Width}x{layer.Raster.Height} at {layer.X},{layer.Y}: {layer.Blend}, {layer.Duration.TotalMilliseconds} ms");
layer.Dispose();
}
// The preview some files carry for quick display, or null.
using Raster? preview = JxlImage.ReadPreview("duck.jxl");
// A lossy still at an eighth of its size, from its LF image alone.
using Raster thumbnail = Raster.Load("duck.jxl", options: new JxlReaderOptions { MaxDownscale = 8 });
Exceptions
- CorruptDataException
The data breaks the format's rules, including data of another format.
ReadPreview(Stream, ReaderOptions?, EgamiContext?)
Reads the preview from a stream; see ReadPreview(string, ReaderOptions?, EgamiContext?).
public static Raster? ReadPreview(Stream stream, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
streamStreamThe file's data, from its start.
optionsReaderOptionsThe general options; the frame range is ignored.
contextEgamiContext
Returns
Examples
// An animation loads as its frames, blended onto the canvas, each with its delay.
using Raster animation = Raster.Load("sprite.jxl");
int frames = animation.FrameCount;
// The layers before blending, for an editor: each at its own size and place.
IReadOnlyList<JxlLayer> layers = JxlImage.ReadLayers("sprite.jxl");
foreach (JxlLayer layer in layers)
{
Console.WriteLine($"{layer.Raster.Width}x{layer.Raster.Height} at {layer.X},{layer.Y}: {layer.Blend}, {layer.Duration.TotalMilliseconds} ms");
layer.Dispose();
}
// The preview some files carry for quick display, or null.
using Raster? preview = JxlImage.ReadPreview("duck.jxl");
// A lossy still at an eighth of its size, from its LF image alone.
using Raster thumbnail = Raster.Load("duck.jxl", options: new JxlReaderOptions { MaxDownscale = 8 });
Exceptions
- CorruptDataException
The data breaks the format's rules, including data of another format.
ReadPreview(string, ReaderOptions?, EgamiContext?)
Reads the preview: a small image some files carry for quick display, in the natural pixel type.
public static Raster? ReadPreview(string path, ReaderOptions? options = null, EgamiContext? context = null)
Parameters
pathstringThe file.
optionsReaderOptionsThe general options; the frame range is ignored.
contextEgamiContext
Returns
Examples
// An animation loads as its frames, blended onto the canvas, each with its delay.
using Raster animation = Raster.Load("sprite.jxl");
int frames = animation.FrameCount;
// The layers before blending, for an editor: each at its own size and place.
IReadOnlyList<JxlLayer> layers = JxlImage.ReadLayers("sprite.jxl");
foreach (JxlLayer layer in layers)
{
Console.WriteLine($"{layer.Raster.Width}x{layer.Raster.Height} at {layer.X},{layer.Y}: {layer.Blend}, {layer.Duration.TotalMilliseconds} ms");
layer.Dispose();
}
// The preview some files carry for quick display, or null.
using Raster? preview = JxlImage.ReadPreview("duck.jxl");
// A lossy still at an eighth of its size, from its LF image alone.
using Raster thumbnail = Raster.Load("duck.jxl", options: new JxlReaderOptions { MaxDownscale = 8 });
Exceptions
- CorruptDataException
The data breaks the format's rules, including data of another format.
RecompressJpeg(Stream, Stream, EgamiContext?)
Recompresses a JPEG from a stream; see RecompressJpeg(string, string, EgamiContext?).
public static void RecompressJpeg(Stream stream, Stream output, EgamiContext? context = null)
Parameters
streamStreamThe JPEG's data, from its start.
outputStreamWhere to write the JPEG XL file.
contextEgamiContext
Examples
// A JPEG becomes a JPEG XL file about a fifth smaller with the same pixels, and comes back byte for byte.
JxlImage.RecompressJpeg("duck.jpg", "duck.jxl");
JxlImage.ReconstructJpeg("duck.jxl", "duck-again.jpg");
Exceptions
- UnsupportedFormatException
The JPEG uses something JPEG XL cannot keep.
- CorruptDataException
The JPEG breaks the format's rules.
RecompressJpeg(string, string, EgamiContext?)
Recompresses a JPEG into JPEG XL without loss, about a fifth smaller (design question 8): the JPEG's quantized coefficients become the JPEG XL image, so Load shows the same pixels a JPEG decoder would, and ReconstructJpeg(string, string, EgamiContext?) gives the original file back byte for byte. The file is what cjxl makes at its default effort, with the ICC profile in the codestream and Exif and XMP in boxes.
public static void RecompressJpeg(string path, string outputPath, EgamiContext? context = null)
Parameters
pathstringThe JPEG file.
outputPathstringThe JPEG XL file to write.
contextEgamiContext
Examples
// A JPEG becomes a JPEG XL file about a fifth smaller with the same pixels, and comes back byte for byte.
JxlImage.RecompressJpeg("duck.jpg", "duck.jxl");
JxlImage.ReconstructJpeg("duck.jxl", "duck-again.jpg");
Exceptions
- UnsupportedFormatException
The JPEG uses something JPEG XL cannot keep: arithmetic coding, 12-bit samples, CMYK or four components, or sampling other than 4:4:4, 4:2:0, 4:2:2 and 4:4:0.
- CorruptDataException
The JPEG breaks the format's rules.
ReconstructJpeg(Stream, Stream, EgamiContext?)
Writes the original JPEG of a recompressed JPEG XL file to a stream; see ReconstructJpeg(string, string, EgamiContext?).
public static void ReconstructJpeg(Stream stream, Stream output, EgamiContext? context = null)
Parameters
streamStreamThe JPEG XL file's data, from its start.
outputStreamWhere to write the JPEG.
contextEgamiContext
Examples
// A JPEG recompressed into JPEG XL loads as pixels like any other file, and gives its JPEG back byte for byte.
using Raster image = Raster.Load("recompressed.jxl");
if (((JxlDetails)image.Metadata.FormatDetails!).HasJpegReconstruction)
{
JxlImage.ReconstructJpeg("recompressed.jxl", "original.jpg");
}
Exceptions
- UnsupportedFormatException
The file has no JPEG reconstruction data, or its frame is not one Egami can rebuild a JPEG from.
- CorruptDataException
The data breaks the format's rules, including data of another format.
ReconstructJpeg(string, string, EgamiContext?)
Writes the JPEG a JPEG XL file was losslessly recompressed from, byte for byte (design question 8). Load decodes such a file to pixels like any other; this gives the original JPEG back instead, when HasJpegReconstruction.
public static void ReconstructJpeg(string path, string outputPath, EgamiContext? context = null)
Parameters
pathstringThe JPEG XL file.
outputPathstringThe JPEG file to write.
contextEgamiContext
Examples
// A JPEG recompressed into JPEG XL loads as pixels like any other file, and gives its JPEG back byte for byte.
using Raster image = Raster.Load("recompressed.jxl");
if (((JxlDetails)image.Metadata.FormatDetails!).HasJpegReconstruction)
{
JxlImage.ReconstructJpeg("recompressed.jxl", "original.jpg");
}
Exceptions
- UnsupportedFormatException
The file has no JPEG reconstruction data, or its frame is not one Egami can rebuild a JPEG from.
- CorruptDataException
The data breaks the format's rules, including data of another format.
WriteLayers(Stream, int, int, IReadOnlyList<JxlLayer>, JxlWriterOptions?, EgamiContext?)
Writes layers to a stream; see WriteLayers(string, int, int, IReadOnlyList<JxlLayer>, JxlWriterOptions?, EgamiContext?).
public static void WriteLayers(Stream stream, int width, int height, IReadOnlyList<JxlLayer> layers, JxlWriterOptions? options = null, EgamiContext? context = null)
Parameters
streamStreamWhere to write the file.
widthintThe canvas width.
heightintThe canvas height.
layersIReadOnlyList<JxlLayer>The layers, bottom first.
optionsJxlWriterOptionsThe options, or null for lossless at the default effort.
contextEgamiContext
Examples
// Layers for an editor: each at its own place, blended onto the ones below, and named. ReadLayers gives them back.
using Raster<Rgba8> photo = Raster.Load<Rgba8>("duck.png");
Raster<Rgba8> badge = Raster.Create<Rgba8>(120, 60, new Rgba8(255, 200, 0, 160));
List<JxlLayer> layers =
[
new(photo.As<Rgba8>(), name: "photo"),
new(badge, x: -20, y: 30, blend: JxlLayerBlend.Blend, name: "badge"),
];
JxlImage.WriteLayers("layered.jxl", photo.Width, photo.Height, layers);
foreach (JxlLayer layer in layers)
{
layer.Dispose();
}
// Load gives them blended; ReadLayers as they were written.
using Raster flat = Raster.Load("layered.jxl");
IReadOnlyList<JxlLayer> read = JxlImage.ReadLayers("layered.jxl");
Exceptions
- ArgumentNullException
- ArgumentOutOfRangeException
widthorheightis not positive, or above 2³⁰.- ArgumentException
layersis empty, or a layer lasts longer than 2³² − 1 ms.
WriteLayers(string, int, int, IReadOnlyList<JxlLayer>, JxlWriterOptions?, EgamiContext?)
Writes layers as one frame each, so that ReadLayers(string, ReaderOptions?, EgamiContext?) gives them back
with their place, blend mode, duration and name, and Load gives them blended. Each layer blends onto the canvas made by
the ones before it, the first onto a transparent black canvas. All layers take the first one's pixel format (gray or
color, and its sample type) and, when any layer has alpha, alpha; others are converted. The file is lossless unless
options sets Lossless to false or a
Distance, and animated when any layer has a duration.
public static void WriteLayers(string path, int width, int height, IReadOnlyList<JxlLayer> layers, JxlWriterOptions? options = null, EgamiContext? context = null)
Parameters
pathstringThe file to write.
widthintThe canvas width.
heightintThe canvas height.
layersIReadOnlyList<JxlLayer>The layers, bottom first.
optionsJxlWriterOptionsThe options, or null for lossless at the default effort; FirstFrameOnly is ignored.
contextEgamiContext
Examples
// Layers for an editor: each at its own place, blended onto the ones below, and named. ReadLayers gives them back.
using Raster<Rgba8> photo = Raster.Load<Rgba8>("duck.png");
Raster<Rgba8> badge = Raster.Create<Rgba8>(120, 60, new Rgba8(255, 200, 0, 160));
List<JxlLayer> layers =
[
new(photo.As<Rgba8>(), name: "photo"),
new(badge, x: -20, y: 30, blend: JxlLayerBlend.Blend, name: "badge"),
];
JxlImage.WriteLayers("layered.jxl", photo.Width, photo.Height, layers);
foreach (JxlLayer layer in layers)
{
layer.Dispose();
}
// Load gives them blended; ReadLayers as they were written.
using Raster flat = Raster.Load("layered.jxl");
IReadOnlyList<JxlLayer> read = JxlImage.ReadLayers("layered.jxl");
Exceptions
- ArgumentNullException
- ArgumentOutOfRangeException
widthorheightis not positive, or above 2³⁰.- ArgumentException
layersis empty, or a layer lasts longer than 2³² − 1 ms.