PixelForge 0.1.0-preview.1

This is a prerelease version of PixelForge.
dotnet add package PixelForge --version 0.1.0-preview.1
                    
NuGet\Install-Package PixelForge -Version 0.1.0-preview.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PixelForge" Version="0.1.0-preview.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PixelForge" Version="0.1.0-preview.1" />
                    
Directory.Packages.props
<PackageReference Include="PixelForge" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PixelForge --version 0.1.0-preview.1
                    
#r "nuget: PixelForge, 0.1.0-preview.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PixelForge@0.1.0-preview.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PixelForge&version=0.1.0-preview.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=PixelForge&version=0.1.0-preview.1&prerelease
                    
Install as a Cake Tool

<p align="center"><img src="icon.png" width="96" alt="PixelForge logo"></p>

PixelForge

Familiar API, MIT, no license key, safe defaults for user uploads.

PixelForge is an image processing library for .NET 8+ built on SkiaSharp. It covers the everyday jobs: load an upload, fix its orientation, resize or crop it, and save it as JPEG, PNG or WebP. If you have used ImageSharp, you already know the API.

CI NuGet

dotnet add package PixelForge

Quick start

using PixelForge;
using PixelForge.Processing;

using var image = Image.Load("photo.jpg");
image.Mutate(x => x.AutoOrient().Resize(800, 0));
image.SaveAsWebp("photo.webp", quality: 80);

Why PixelForge

  • MIT, no license key, no build-time checks. Use it in open source, closed source and CI without registration.
  • Safe by default for uploads.
    • Decompression bombs are rejected from the header before any pixel memory is allocated (MaxPixels, default 100 MP).
    • Input size is capped (MaxBytes).
    • EXIF metadata, including GPS location, is never written to output.
    • See docs/security.md.
  • Fast thumbnails. DecoderOptions.TargetSize decodes JPEG and WebP directly at reduced size. See benchmarks.
  • Runs everywhere .NET runs on servers. Windows, macOS, Debian/Ubuntu and Alpine containers, x64 and arm64, with no apt-get or apk add. CI checks every one of these.
  • Two dependencies: SkiaSharp and its Linux native assets.

Thumbnails from uploads (ASP.NET Core)

app.MapPost("/thumbnail", async (IFormFile file, CancellationToken ct) =>
{
    var size = new Size(200, 200);
    var options = new DecoderOptions { MaxPixels = 40_000_000, TargetSize = size };

    try
    {
        await using var input = file.OpenReadStream();
        using var image = await Image.LoadAsync(input, options, ct);
        image.Mutate(x => x.AutoOrient().Resize(new ResizeOptions { Size = size, Mode = ResizeMode.Max }));

        var output = new MemoryStream();
        await image.SaveAsWebpAsync(output, 80, cancellationToken: ct);
        output.Position = 0;
        return Results.File(output, "image/webp");
    }
    catch (ImageTooLargeException) { return Results.StatusCode(413); }
    catch (ImageFormatException) { return Results.BadRequest(); }
}).DisableAntiforgery();

Full sample with Dockerfiles for Debian and Alpine: samples/UploadApi.

Features

Load Load(path \| Stream \| byte[] \| ReadOnlySpan<byte>), LoadAsync(Stream), Identify (header only)
Formats in PNG, JPEG, WebP, GIF (first frame), BMP, ICO, WBMP
Formats out JPEG, PNG, WebP (lossy and lossless)
Operations AutoOrient, Resize (Crop, Pad, Max, Min, Stretch + anchor), Crop, Rotate, Flip, Grayscale
Limits MaxPixels, MaxBytes, TargetSize

Not included: pixel access, drawing and text, metadata editing, animation, TIFF. See the full list. Open an issue if you need one of these.

Coming from ImageSharp?

For most upload and thumbnail code you change only the using lines and the encoder calls:

-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats.Jpeg;
-using SixLabors.ImageSharp.Processing;
+using PixelForge;
+using PixelForge.Processing;

 using var image = await Image.LoadAsync(stream);
 image.Mutate(x => x.AutoOrient().Resize(new ResizeOptions { Size = new Size(800, 600), Mode = ResizeMode.Max }));
-await image.SaveAsJpegAsync(output, new JpegEncoder { Quality = 80 });
+await image.SaveAsJpegAsync(output, 80);

The migration guide has the full mapping table and the differences in behavior.

Benchmarks

Decode a 4000×3000 JPEG (2.9 MB, quality 90), resize, encode JPEG quality 75 to memory. Each library uses its documented API.

  • Resize: plain decode, then resize to 800×600.
  • Thumbnail: fit into 200×200, using each library's decode-time downscaling where it has one:
    • PixelForge and ImageSharp: TargetSize.
    • NetVips: ThumbnailBuffer.
    • Magick.NET: jpeg:size.
Library Resize 4000×3000 → 800×600 Thumbnail 200px Allocated (managed, thumbnail)
PixelForge 0.1 158.1 ms 32.6 ms 8.9 KB
ImageSharp 3.1.12 100.6 ms 40.7 ms 58.2 KB
NetVips 3.2.0 85.6 ms 33.3 ms 9.6 KB
Magick.NET-Q8 15.0.0 444.3 ms 36.8 ms 12.8 KB

BenchmarkDotNet 0.15.8, .NET 10.0.11, Windows 11, AMD Ryzen 5 5500U (6 cores / 12 threads). Source: benchmarks/PixelForge.Benchmarks.

How to read this:

  • Thumbnails, the common upload case: PixelForge is the fastest of the four.
  • Full-size resize: PixelForge is about 1.6× slower than ImageSharp and 1.8× slower than NetVips. It is still about 2.8× faster than Magick.NET.
    • About 106 of the 158 ms is Skia's single-threaded JPEG decode of the full 12 MP image. ImageSharp and libvips parallelize more of the pipeline.
    • If you know the output size, set DecoderOptions.TargetSize to it. The decode then happens at reduced size, which is what makes the thumbnail column fast.
  • "Allocated" is managed memory only. Pixel buffers in all four libraries live in native or pooled memory and are not counted.

Run it yourself: dotnet run -c Release --project benchmarks/PixelForge.Benchmarks -- --filter '*'.

Contributing

Issues and pull requests are welcome. Please read CONTRIBUTING.md first. Report security problems privately as described in SECURITY.md.

License

MIT. SkiaSharp is MIT; Skia is BSD-3-Clause.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1.0-preview.1 7 10/26/2026