PictureSharp.Jxl
0.8.16
dotnet add package PictureSharp.Jxl --version 0.8.16
NuGet\Install-Package PictureSharp.Jxl -Version 0.8.16
<PackageReference Include="PictureSharp.Jxl" Version="0.8.16" />
<PackageVersion Include="PictureSharp.Jxl" Version="0.8.16" />
<PackageReference Include="PictureSharp.Jxl" />
paket add PictureSharp.Jxl --version 0.8.16
#r "nuget: PictureSharp.Jxl, 0.8.16"
#:package PictureSharp.Jxl@0.8.16
#addin nuget:?package=PictureSharp.Jxl&version=0.8.16
#tool nuget:?package=PictureSharp.Jxl&version=0.8.16
PictureSharp.Jxl
JPEG XL for PictureSharp, in pure C# with no native dependencies. Requires .NET 10+ and PictureSharp 0.9.1+.
Install from NuGet:
dotnet add package PictureSharp.Jxl
Usage
Register the format once, then load and save .jxl files like any other image:
using PictureSharp;
using PictureSharp.Formats.Jxl;
ImageConfiguration.Default = ImageConfiguration.Default.ToBuilder().AddFormat(new JxlFormat()).Build();
using var image = Image.Load("photo.jxl", new DecoderOptions { ApplyExifOrientation = true });
image.Mutate(x => x.Resize(1600, 0));
image.SaveAsJxl("small.jxl");
Loading keeps the ICC profile, EXIF and XMP; saving writes them back. Saving is lossy at distance 1.0 like cjxl
by default; new JxlEncoderOptions { Quality = 100 } (or Distance = 0) saves losslessly. Image.EditMetadata changes
the metadata without touching the frames.
To preserve an existing JPEG exactly, use the separate transcoder without loading its pixels:
JxlTranscoder.FromJpeg("original.jpg", "archived.jxl");
JxlTranscoder.ToJpeg("archived.jxl", "restored.jpg"); // byte-identical to original.jpg
// Stream and buffer overloads are also available, e.g. FromJpeg(jpegStream, jxlStream).
Keep 16-bit samples
using Image scan = Image.Load("scan.png", new DecoderOptions { PreserveBitDepth = true });
scan.SaveAsJxl("scan.jxl", new JxlEncoderOptions { Distance = 0 });
This preserves every 16-bit sample, including alpha. Default loading returns 8-bit pixels; enable PreserveBitDepth
when reading the result too.
Support
| Supported | |
|---|---|
| Read | Lossy (VarDCT) and lossless (Modular) images, including recompressed JPEGs, progressive files, patches, photon noise and splines. Premultiplied alpha comes back straight, spot colours are rendered like djxl, and other extra channels (depth, selection masks, thermal, …) are decoded and left out. Layers are flattened like djxl or read one by one with JxlLayers.Load. Animations load whole or frame by frame with Image.OpenFrameReaderAsync. |
| Write | Lossy (Quality/Distance, Effort 1–9) and lossless, 8 or 16 bits; files about as small as cjxl at the same settings. Animations are saved whole or frame by frame with Image.CreateFrameWriter. Film grain with PhotonNoiseIso (lossy). |
| Pixels | Gray or RGB, with or without alpha, up to 16 bits per sample (Rgba64 with PreserveBitDepth, otherwise 8-bit). |
| Metadata | ICC, EXIF, XMP, colour description and orientation: read, written and edited in place. |
| JPEG | JxlTranscoder stores 8-bit Huffman JPEGs (gray or YCbCr) and restores them byte for byte. |
Not supported yet: images with float samples or CMYK need a float pixel type and colour management for CMYK
profiles in PictureSharp itself, so decoding them throws NotSupportedException; transcoding RGB JPEGs.
Format limits: CMYK, arithmetic-coded and 12-bit JPEGs cannot be stored as JPEG XL reconstruction data (libjxl rejects them too).
Output matches djxl (libjxl 0.12.0): lossless exactly, lossy within 1 of 255, and files written here decode the same way with djxl.
CI runs on Linux, including a Native AOT build.
Guides: decoding · encoding · JPEG transcoding · metadata · architecture · release notes
Performance
- SIMD: AVX2/FMA and SSE4.1 kernels with a scalar fallback; all paths produce identical output.
- Native AOT: publish with
-p:IlcInstructionSet=x86-64-v3(ornative) to get the AVX2/FMA kernels; the default target uses SSE4.1 only. - Threads: decoding, encoding and JPEG transcoding run independent groups in parallel. Set
MaxDegreeOfParallelism(-1 = all cores, the default; 1 = single-threaded) onDecoderOptions,JxlEncoderOptionsorJxlTranscoderOptions. The output does not depend on it. - Encoding effort: lower
Effortis faster; lossless efforts 1–3 are several times faster than 7. - Memory: a 12 MP image needs about 180 MiB (JPEG-recompressed decode) to 860 MiB (lossless encode) at its peak, including the 48 MB output or input image.
Measurements: speed.
License
MIT. Ported libjxl sources are listed in THIRD-PARTY-NOTICES.txt.
Build
dotnet build -c Release
dotnet test -c Release
dotnet pack src/PictureSharp.Jxl -c Release --no-build -o artifacts
bash scripts/verify-package-consumer.sh
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- PictureSharp (>= 0.9.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.8.16 | 61 | 11/2/2026 |
| 0.8.15 | 61 | 11/2/2026 |
| 0.8.14 | 53 | 11/2/2026 |
| 0.8.13 | 58 | 11/2/2026 |
| 0.8.12 | 55 | 11/2/2026 |
| 0.8.11 | 57 | 11/2/2026 |
| 0.8.10 | 56 | 11/2/2026 |
| 0.8.9 | 67 | 10/31/2026 |
| 0.8.8 | 67 | 10/31/2026 |
| 0.8.7 | 60 | 10/30/2026 |
| 0.8.6 | 58 | 10/30/2026 |
| 0.8.5 | 56 | 10/30/2026 |
| 0.8.4 | 54 | 10/30/2026 |
| 0.8.3 | 62 | 10/29/2026 |
| 0.8.2 | 59 | 10/29/2026 |
| 0.8.1 | 64 | 10/29/2026 |
| 0.8.0 | 67 | 10/29/2026 |
| 0.7.10 | 57 | 10/28/2026 |
| 0.7.9 | 60 | 10/28/2026 |
| 0.7.8 | 63 | 10/28/2026 |
0.8.16: every JPEG XL extra channel decodes: premultiplied alpha is returned as straight alpha exactly as libjxl unpremultiplies it, spot colours are rendered like djxl, and depth, selection-mask, thermal and other channels are decoded and left out (Image.Load, the frame reader and JxlLayers). CMYK and float samples still throw NotSupportedException, naming the PictureSharp core support they need. Requires PictureSharp 0.9.1. See docs/releases/release-0.8.16.md and docs/design/0.8.16-extra-channels.md.