oneimage

Images for .NET, in pure C#. Nothing else to install.

OneImage is an image library written from the ground up in C#, with no dependency beyond .NET itself. One line for a thumbnail, crop or conversion; underneath, a lazy engine that loads, edits and renders a tile at a time.

dotnet add package RecursiveAI.OneImage

A thumbnail is one line. Nothing is decoded until you save.

Program.cs.NET 10
using OneImage;

// 400 px wide, upright, sRGB, EXIF and GPS removed, saved as WebP.
Image.Thumbnail("in.jpg", 400).Save("thumb.webp");

// Load, edit, save. The format follows the extension.
Image.Load("in.jpg")
    .Resize(width: 1200)
    .Rotate(90)
    .Save("out.png");

Lazy, tiled, streaming

Operations record what to do; pixels are computed tile by tile on save. A 24 MP photo becomes a thumbnail without being held at full size, and JPEGs decode at 1/2, 1/4 or 1/8 scale when that is enough.

Color and metadata

ICC v2 and v4 profiles, CMYK to sRGB, resampling in linear light. EXIF orientation is applied for you, and thumbnails strip GPS by default.

Safe on files you didn’t write

Parsers and decoders are bounds-checked C#. Size limits are on by default and checked from headers before anything large is allocated. Every decoder is fuzzed.

Small to ship

No native binaries, no reflection, no dynamic code. NativeAOT and trimming are supported, and you can leave out the codecs you don’t use.

Performance

Faster than ImageSharp on 27 of 29 tasks.

One task is a tie: a watermark, 4.9 ms each. One is slower: converting a CMYK JPEG to sRGB takes 1.64× as long, because OneImage applies the embedded ICC profile and ImageSharp skips it, so it is not a like-for-like comparison.

Native wrappers win some tasks. NetVips reads multi-page TIFF about 3× faster at OneImage’s default thread limit, encodes JPEG 1.58× faster and one PNG input 2.29× faster; SkiaSharp decodes GIF 2.23× faster. A JPEG thumbnail uses about 1 MiB more peak memory than ImageSharp’s.

How many times faster OneImage is than ImageSharp 3.1.12

Wall-clock time, log scale, longer is better. Bars left of 1× are slower.

  1. thumb-jpeg1.25×
  2. thumb-webp1.39×
  3. png-to-webp (natural)19.1×
  4. png-to-webp (photo)11.3×
  5. png-to-webp (screenshot)2.5×
  6. jpeg-decode1.9×
  7. jpeg-encode1.15×
  8. png-decode (natural)3.4×
  9. png-decode (photo)1.21×
  10. png-decode (screenshot)1.45×
  11. png-encode (natural)4.8×
  12. png-encode (photo)6.1×
  13. png-encode (screenshot)1.9×
  14. webp-decode (lossy)1.8×
  15. webp-decode (lossless)2.7×
  16. webp-encode (lossless 2000×1500)7.5×
  17. webp-encode (lossy 2000×1500)5.8×
  18. webp-encode (lossy 400×300)4.4×
  19. gif-decode2.7×
  20. gif-encode1.26×
  21. gif-resize1.17×
  22. tiff-multipage-decode7.0×
  23. tiff-encode3.0×
  24. bmp-decode1.8×
  25. bmp-encode1.8×
  26. upscale-2x2.0×
  27. watermark1.00× tie
  28. cmyk-jpeg-to-srgb0.61× slower
  29. jpeg-decode-rgba1.8×

Measured with BenchmarkDotNet on one shared workstation (AMD Ryzen 9 7950X3D, .NET 10). Local measurements, not promises for your hardware. Full results, memory and the method ↗

Formats

Formats are detected by content, not extension. If you need one of those formats, or ImageMagick’s long tail of operations, another library is the better choice; the comparison says which.

Get started