Encoding
Baseline and progressive JPEG, perceptual quality or distance, chroma subsampling and custom scan scripts.
Pure managed JPEG encoding for .NET.
DotJpegli is a safe, portable C# JPEG encoder based on Google Jpegli. Encode RGB or grayscale pixels as baseline or progressive JPEG, with control over quality, sampling, color profiles and metadata.
The library is implemented entirely in managed .NET, with no native dependencies, P/Invoke, unsafe code or runtime NuGet dependencies. NativeAOT and trimming are fully supported on .NET 10 and .NET 11.
Visual & Perceptual Evaluation
Fine clouds of dust, saturated colour and thousands of stars make Webb's Cosmic Cliffs a demanding subject. Open the 2400 × 1390 source photograph to inspect its full detail:
Every encoder receives the same RGB pixels. Links open the complete files; sizes include headers and metadata. SSIMULACRA2 measures each decoded image against the source; higher scores indicate closer agreement with that metric.
| Encoder / source | Settings | File size | SSIMULACRA2 |
|---|---|---|---|
| Source PNG | Lossless common input | 4,437,354 bytes · 4333.4 KiB | 100.00 |
| DotJpegli 4.0.0 | Distance 1, 4:2:0, progressive level 2 | 723,724 bytes · 706.8 KiB | 80.49 |
| Google's C++ jpegli | Distance 1, 4:2:0, progressive level 2 | 723,938 bytes · 707.0 KiB | 80.49 |
| mozjpeg 4.1.1 | Quality 90, 4:2:0, progressive, trellis | 726,330 bytes · 709.3 KiB | 78.92 |
| libjpeg-turbo 3.2.0 | Quality 90, 4:2:0, progressive | 822,647 bytes · 803.4 KiB | 80.41 |
| WebP 1.6.0 | Quality 90, method 6 | 640,770 bytes · 625.8 KiB | 82.28 |
| AVIF · libavif 1.4.2 / libaom 3.14.1 | Quality 90, speed 6, 8-bit 4:2:0 | 837,683 bytes · 818.0 KiB | 86.85 |
| JPEG XL · libjxl 0.12.0 | Distance 1, effort 7 | 759,353 bytes · 741.6 KiB | 88.02 |
These are selected high-quality settings for one photograph. Quality scales differ across codecs, and these outputs are not matched perceptual quality. JPEG XL and AVIF retain more detail according to this metric at the settings shown. DotJpegli is 214 bytes smaller than Google's jpegli here; their bytes and decoded pixels differ slightly. JPEG XL requires a compatible viewer.
The following lossless sheet shows the same 480 × 300 detail from every image, with one source pixel per image pixel. Open it at full size to compare star edges, wispy dust and colour transitions:
Capabilities
Full-featured JPEG compression implemented in safe, portable managed C# without native binaries or runtime dependencies.
Baseline and progressive JPEG, perceptual quality or distance, chroma subsampling and custom scan scripts.
RGB, BGR, grayscale and other layouts; byte, ushort and float sources; configurable row stride.
ICC profiles and source color conversion, Exif, XMP, IPTC, comments and raw metadata markers.
Byte arrays or streams, cancellation and optional parallel encoding.
Managed SIMD on .NET 10 and .NET 11, with scalar fallbacks.
Zero unsafe blocks, zero P/Invoke, zero runtime NuGet dependencies, and full trimming and NativeAOT compatibility.
Standalone Tooling
Download a self-contained NativeAOT dotjpegli package or portable archive from
Releases. Downloads are
available for Windows (x64, ARM64), Linux (x64, ARM64) and macOS (ARM64),
and do not require .NET to be installed.
dotjpegli encode input.png output.jpg --quality 90 --progressive
dotjpegli encode input.png output.jpg --distance 1 --subsampling 444 --threads 4
See the CLI guide for installation, options and local publishing.
Per-user .msi installer (adds dotjpegli to user PATH), portable .zip archive and standalone .exe executable.
Debian/Ubuntu .deb, Fedora/RHEL/openSUSE .rpm, single-file .AppImage, .flatpak bundle and portable .tar.gz.
Apple Silicon .pkg installer (installs /usr/local/bin/dotjpegli) and ad-hoc signed portable .tar.gz archive.
Library API
Add the NuGet package to any .NET Standard 2.1, .NET 10 or .NET 11 project and encode pixels to a byte array or stream.
dotnet add package DotJpegli --version 4.0.0
Supports .NET Standard 2.1, .NET 10 and .NET 11.
dotnet add path/to/YourApp.csproj reference src/DotJpegli/DotJpegli.csproj
Building from source requires .NET SDK 11.0.100-rc.3.26522.148, pinned in
global.json
with prerelease SDKs enabled.
using DotJpegli;
byte[] rgbPixels = [255, 0, 0]; // One red pixel, in R, G, B order.
byte[] jpeg = JpegliEncoder.Encode(rgbPixels, width: 1, height: 1, options: new()
{
Quality = 85
});
File.WriteAllBytes("output.jpg", jpeg);
For RGB input, the defaults are baseline JPEG, quality 85 and 4:2:0 chroma subsampling. For other pixel layouts, row padding and higher-precision sources, see the encoding guide. Alpha channels are ignored; composite translucent pixels before encoding.
using FileStream output = File.Create("progressive.jpg");
JpegliEncoder.Encode(output, rgbPixels, width: 1, height: 1, options: new()
{
Quality = 85,
Progressive = true
});
The stream overload avoids retaining the complete encoded JPEG in a returned byte array. See compression and scan options for quality, sampling and progression controls.
Benchmarks & Evidence
These charts compare DotJpegli with native Google Jpegli on 24 Kodak photographs.
Mean JPEG sizes differ from native by at most 0.032% at matched PSNR and SSIM.
On an AMD EPYC 9V45, progressive encoding averaged 29.6–30.5% less time than native; sequential averaged 15.7–16.8% less.
DotJpegli averaged 98.8–146.3 KiB of managed GC allocations per encode, compared with 1,924.8–4,288.3 KiB of native heap requests for Google Jpegli (measurements, including the output JPEG; not peak memory).
See methodology and full results and chart data. The full comparison does not meet native performance parity.
Reference Guides
Detailed guides covering pixel layouts, ICC color profiles, scan scripts, quantization tables, parity evidence and release engineering.
Pixel layouts, sampling, streams and color spaces.
ICC profiles, Exif, XMP, IPTC and metadata editing.
Quality, distance, scan scripts, parallel execution and memory use.
NativeAOT CLI usage, portable downloads and Windows, Linux and macOS packages.
Standard and custom tables, transfer functions and advanced tuning.
Source builds, focused tests, reproducibility and deployment checks.
Trusted publishing setup and publishing a tested package from CI.
Comparison scope, acceptance bounds and hosted evidence.
Measurement scope, encoding latency and CI diagnostics.
Licensed high-resolution source, seven encoder outputs, file sizes and reproduction instructions.
DotJpegli produces lossy, eight-bit JPEG, including from higher-precision sources and even at quality 100. Jpegli's quality scale is not interchangeable with libjpeg's. Decoding is outside the project's scope.
Quality and compression parity with upstream is established within a documented RGB8 YCbCr scope. Byte-identical upstream output is not claimed. Performance results and acceptance bounds are documented separately.