PictureSharp.Jxl
0.8.2
See the version list below for details.
dotnet add package PictureSharp.Jxl --version 0.8.2
NuGet\Install-Package PictureSharp.Jxl -Version 0.8.2
<PackageReference Include="PictureSharp.Jxl" Version="0.8.2" />
<PackageVersion Include="PictureSharp.Jxl" Version="0.8.2" />
<PackageReference Include="PictureSharp.Jxl" />
paket add PictureSharp.Jxl --version 0.8.2
#r "nuget: PictureSharp.Jxl, 0.8.2"
#:package PictureSharp.Jxl@0.8.2
#addin nuget:?package=PictureSharp.Jxl&version=0.8.2
#tool nuget:?package=PictureSharp.Jxl&version=0.8.2
PictureSharp.Jxl
JPEG XL for PictureSharp, in pure C# with no native dependencies. Requires .NET 10+ and PictureSharp 0.9.0+.
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. See what changed in 0.7.8.
Support
- Read: still images as
cjxlproduces them: lossy (VarDCT) and lossless (Modular), recompressed JPEGs, progressive files, patches; RGB and grayscale with alpha, up to 16 bits per sample (Rgba64withPreserveBitDepth, otherwise reduced to 8). - Write: lossy VarDCT with
Quality/DistanceandEffort1–9, about as small ascjxlat the same settings (patches included); lossless 8-bit or 16-bit gray or RGB with alpha, about as small ascjxl -d 0 -e 7. - Metadata: ICC, EXIF, XMP (also Brotli-compressed), colour description and orientation; read, written and edited in place (editing files with JPEG reconstruction data is unsupported).
- JPEG transcoding:
JxlTranscoder.FromJpegstores sequential or progressive 8-bit Huffman JPEG (gray or YCbCr 4:4:4/4:2:2/4:2:0);ToJpegreconstructs the original JPEG byte for byte, including metadata. - Not supported yet: animations, layers, photon noise and splines, float samples, CMYK
(
NotSupportedException); writing animations; transcoding RGB, CMYK/YCCK, arithmetic or 12-bit JPEG.
Pixels match djxl (libjxl 0.12.0): lossless images exactly, lossy ones within 1 of 255 in a few samples. Files this package writes decode with djxl the same way.
Version 0.8.0 adds SIMD kernels (AVX2 with FMA, SSE4.1, scalar fallback) with byte-identical results to 0.7.10:
on an AVX2 CPU, VarDCT decoding is 2.8–3.8× and lossy encoding 1.4–2.6× faster, single-threaded. Native AOT
applications get the AVX2/FMA kernels only when published with -p:IlcInstructionSet=x86-64-v3 (or native).
See the release notes and speed measurements.
Version 0.8.1 decodes and encodes independent groups, tiles and row bands in parallel, with byte-identical output at
any thread count: DecoderOptions.MaxDegreeOfParallelism (PictureSharp core), JxlEncoderOptions and
JxlTranscoderOptions.MaxDegreeOfParallelism (default -1, all cores; 1 = single-threaded). On 16 logical CPUs
lossless decoding is 5–8×, VarDCT decoding 1.9–3.2× and lossy encoding 3.1–4.6× faster than on one thread. See the
release notes and speed measurements.
Version 0.8.2 also parallelizes JPEG reconstruction and lossless tree learning and shrinks the lossy encoder's per-worker scratch, with output identical to 0.8.1. On 16 logical CPUs JPEG reconstruction is 4.2× and lossless encoding (effort 7) 1.3–2.8× faster than 0.8.1. See the release notes and speed measurements.
Status: early development (0.8.2). Not for production use yet; the API may change. CI runs on Linux, including a Native AOT build.
Guides: decoding · encoding · JPEG transcoding · metadata · architecture · release notes
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.0)
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 | 99 | 11/2/2026 |
| 0.8.15 | 97 | 11/2/2026 |
| 0.8.14 | 87 | 11/2/2026 |
| 0.8.13 | 90 | 11/2/2026 |
| 0.8.12 | 88 | 11/2/2026 |
| 0.8.11 | 91 | 11/2/2026 |
| 0.8.10 | 90 | 11/2/2026 |
| 0.8.9 | 101 | 10/31/2026 |
| 0.8.8 | 102 | 10/31/2026 |
| 0.8.7 | 94 | 10/30/2026 |
| 0.8.6 | 90 | 10/30/2026 |
| 0.8.5 | 90 | 10/30/2026 |
| 0.8.4 | 88 | 10/30/2026 |
| 0.8.3 | 94 | 10/29/2026 |
| 0.8.2 | 93 | 10/29/2026 |
| 0.8.1 | 96 | 10/29/2026 |
| 0.8.0 | 101 | 10/29/2026 |
| 0.7.10 | 90 | 10/28/2026 |
| 0.7.9 | 94 | 10/28/2026 |
| 0.7.8 | 96 | 10/28/2026 |
0.8.2: scheduling and scratch. JPEG reconstruction writes DC-first scans in parallel chunks with a 64-bit bit accumulator; MA-tree learning, RCT choice and palette discovery run in parallel; lossy encoder search scratch sized for DCT64x64. Output identical to 0.8.1 at every thread count. vs 0.8.1 on 16 logical CPUs: JPEG reconstruction 4.2x, lossless encode (effort 7) 1.3-2.8x, lossy encode effort 1-3 7.6% faster with 3x less allocation; 1 thread: JPEG reconstruction 20% faster, other cases within noise. No API changes. See docs/releases/release-0.8.2.md and docs/benchmarks/speed.md.