PictureSharp.Jxl
0.8.9
See the version list below for details.
dotnet add package PictureSharp.Jxl --version 0.8.9
NuGet\Install-Package PictureSharp.Jxl -Version 0.8.9
<PackageReference Include="PictureSharp.Jxl" Version="0.8.9" />
<PackageVersion Include="PictureSharp.Jxl" Version="0.8.9" />
<PackageReference Include="PictureSharp.Jxl" />
paket add PictureSharp.Jxl --version 0.8.9
#r "nuget: PictureSharp.Jxl, 0.8.9"
#:package PictureSharp.Jxl@0.8.9
#addin nuget:?package=PictureSharp.Jxl&version=0.8.9
#tool nuget:?package=PictureSharp.Jxl&version=0.8.9
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.
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, with libjxl's effort tiers and about as small ascjxl -d 0at the same effort. - 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.
Status: early development (0.8.9). 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
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.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 | 102 | 11/2/2026 |
| 0.8.15 | 100 | 11/2/2026 |
| 0.8.14 | 90 | 11/2/2026 |
| 0.8.13 | 93 | 11/2/2026 |
| 0.8.12 | 91 | 11/2/2026 |
| 0.8.11 | 94 | 11/2/2026 |
| 0.8.10 | 93 | 11/2/2026 |
| 0.8.9 | 103 | 10/31/2026 |
| 0.8.8 | 103 | 10/31/2026 |
| 0.8.7 | 95 | 10/30/2026 |
| 0.8.6 | 91 | 10/30/2026 |
| 0.8.5 | 91 | 10/30/2026 |
| 0.8.4 | 89 | 10/30/2026 |
| 0.8.3 | 95 | 10/29/2026 |
| 0.8.2 | 94 | 10/29/2026 |
| 0.8.1 | 97 | 10/29/2026 |
| 0.8.0 | 102 | 10/29/2026 |
| 0.7.10 | 91 | 10/28/2026 |
| 0.7.9 | 95 | 10/28/2026 |
| 0.7.8 | 97 | 10/28/2026 |
0.8.9: decoding and ToJpeg charge their working memory against MaxPixels (64 bytes per allowed pixel plus 64 MiB), so a small file declaring many extra channels can no longer allocate gigabytes, and MaxFrames counts frames that are not displayed. Cancellation now stops a 12 MP encode within 35 ms (it could take over 100 ms). Fuzzing of cancellation at every allocation, failing streams, returned buffers, the encoder and metadata editing found no other defect. Decoded pixels and encoded bytes are unchanged. No API changes. See docs/releases/release-0.8.9.md and docs/design/0.8.9-resilience.md.