A pure C# .NET 10 port of ImageMagick. Zero native dependencies. Full AOT compatibility. No P/Invoke, no C/C++ bindings — just managed code competing at native speed.
ImageMagick is the gold standard for image processing, but it's written in C — a language that has allowed memory corruption, buffer overflows, and CVEs to accumulate for decades. .NET 10 has matured to the point where C# can compete with C and C++ in raw performance when used with care: Span<T>, hardware intrinsics (SSE2/SSE4.1/AVX2/AVX-512), stackalloc, ArrayPool<T>, and aggressive JIT inlining.
SharpImage reimplements ImageMagick's image processing pipeline entirely in safe, managed C# and with better performance — producing a library DLL, a CLI tool, and a GUI Photoshop style example project.
| Category | Formats |
|---|---|
| Common Raster | PNG, JPEG, GIF, BMP, TGA, TIFF, WebP, ICO |
| Modern Codecs | AVIF, HEIC, JPEG 2000, JPEG XL, OpenEXR |
| Professional | PSD, DPX, Cineon, HDR (Radiance), FITS, DICOM |
| Compact | QOI, Farbfeld, WBMP, PNM (PBM/PGM/PPM), PCX |
| Legacy/Niche | XBM, XPM, DDS, SGI, PIX, SUN |
| Vector/Document | SVG (rasterized), PDF |
sRGB, Linear RGB, scRGB, Adobe98, ProPhoto, Display P3, Lab, LCHab, LCHuv, Luv, OkLab, OkLCH, Jzazbz, XYZ, xyY, LMS, CAT02 LMS, HSL, HSV, HSB, HSI, HCL, HCLp, HWB, CMY, CMYK, YCbCr (Rec.601 & Rec.709), YCC, YDbDr, YIQ, YPbPr, YUV, OHTA, Gray, Linear Gray, Log, Transparent
Nearest Neighbor · Bilinear · Bicubic · Lanczos2/3/4/5 · Mitchell · Catrom · Hermite · Triangle · Gaussian · Spline · Sinc · Hann · Hamming · Blackman · Kaiser · Parzen · Bohman · Welch · Bartlett · Lagrange
Over · Multiply · Screen · Overlay · Darken · Lighten · ColorDodge · ColorBurn · HardLight · SoftLight · Difference · Exclusion · Add · Subtract · Plus · Minus · Dissolve · Bumpmap · Atop · In · Out · Xor · HardMix · VividLight · LinearLight · PinLight · ModulusAdd · ModulusSubtract · Replace
| Category | Examples |
|---|---|
| Blur & Noise | Gaussian, Motion, Radial, Selective, Bilateral, Kuwahara, Wavelet Denoise, Despeckle, Spread |
| Artistic | Oil Paint, Charcoal, Sketch, Pencil, Vignette, Wave, Swirl, Implode, Emboss |
| Color Grading | Color Transfer, Split Toning, Gradient Map, Channel Mixer, Photo Filter, Duotone |
| Creative Filters | Lens Blur, Tilt-Shift, Glow, Pixelate, Crystallize, Pointillize, Halftone |
| Enhancement | Equalize, Normalize, AutoLevel, AutoGamma, CLAHE, Sigmoidal Contrast, White Balance, Curves |
| Retouching | Inpaint, Clone Stamp, Healing Brush, Red Eye Removal |
| Selection | Flood Select, Color Select, GrabCut, Feather, Alpha Matting |
| HDR | HDR Merge, Reinhard/Drago Tonemapping, Exposure Fusion |
| Analysis | Canny Edge, Hough Lines, Perceptual Hash, Connected Components, Mean Shift Segmentation |
| Transform | Resize, Crop, Rotate, Flip, Flop, Transpose, Distort, Deskew, Trim, Seam Carving, Smart Crop, Affine, Liquify |
| Game Dev | Sprite Sheet Generation, Cubemap Extract/Stitch |
| Decoration | Border, Frame, Raise, Shade, Shear |
| Morphology | Erode, Dilate, Open, Close, TopHat, BottomHat, Hit-and-Miss, Skeleton, Thinning |
| Fourier | FFT Forward/Inverse |
Benchmarks on .NET 10.0.3 with AVX-512, ShortRun (BenchmarkDotNet):
| Operation | Input Size | Time | Memory |
|---|---|---|---|
| Resize Nearest | 256→128 | 46 µs | 116 KB |
| Resize Lanczos3 | 256→128 | 236 µs | 110 KB |
| Resize Lanczos3 | 1024→512 | 1,328 µs | 106 KB |
| Resize Lanczos3 (upscale) | 1024→2048 | 4,616 µs | 298 KB |
| GaussianBlur σ=1.0 | 256×256 | 487 µs | 266 KB |
| GaussianBlur σ=1.0 | 512×512 | 1,403 µs | 10 KB |
| Sharpen | 256×256 | 524 µs | 397 KB |
| MotionBlur r=5 | 512×512 | 2,001 µs | 6 KB |
| Equalize | 256×256 | 245 µs | 396 KB |
| Normalize | 256×256 | 124 µs | 387 KB |
| PNG Encode | 512×512 | 7.2 ms | 37 KB |
| PNG Decode | 512×512 | 1.0 ms | 777 KB |
| JPEG Encode Q85 | 512×512 | 10.0 ms | 73 KB |
| JPEG Decode | 512×512 | 9.8 ms | 3,462 KB |
| MSE Compare | 256×256 | 20 µs | 0 B |
| SSIM Compare | 256×256 | 296 µs | 0 B |
| RGB→Lab (100K pixels) | per-pixel | 21 µs | 0 B |
| Composite Over | 512+256 | 238 µs | 1,536 KB |
| CannyEdge | 256×256 | 1,204 µs | 1,880 KB |
| SeamCarving | 256→200 | 10.2 ms | 440 KB |
- Zero-allocation hot paths —
Span<T>,stackalloc, andArrayPool<T>keep the GC out of per-pixel work - SIMD everywhere — Resize, blur, compositing, and pixel conversion use
Vector256/Vector128with FMA where available - Branchless arithmetic — Critical inner loops avoid conditional branching
- Bounds-check elimination — Span iteration patterns that let the JIT remove safety checks
- Cache-friendly layout — Row-major pixel storage with struct-based pixel types
- .NET 10 SDK or later
dotnet add package Echostorm.SharpImageOr via the Package Manager Console:
Install-Package Echostorm.SharpImagegit clone https://github.com/Echostorm44/SharpImage.git
cd SharpImage
dotnet build -c ReleaseThe test suite uses TUnit with 1,400+ tests covering formats, colorspaces, transforms, effects, compositing, and edge cases.
# Run the full test suite
dotnet run --project tests/SharpImage.Tests -c Release
# Run tests matching a filter
dotnet run --project tests/SharpImage.Tests -c Release -- --filter "*Png*"BigTest is an integration harness that invokes the SharpImage CLI and compares output against ImageMagick. It requires a published AOT build of the CLI first.
# 1. Publish the CLI (AOT)
dotnet publish src/SharpImage.Cli -c Release
# 2. Run BigTest
dotnet run --project tests/SharpImage.BigTest -c ReleasePerformance benchmarks use BenchmarkDotNet. Always run in Release mode — Debug builds produce meaningless numbers.
# Run all benchmarks
dotnet run --project benchmarks/SharpImage.Benchmarks -c Release
# Run a specific benchmark class or filter
dotnet run --project benchmarks/SharpImage.Benchmarks -c Release -- --filter *Resize*
# List available benchmarks without running them
dotnet run --project benchmarks/SharpImage.Benchmarks -c Release -- --list flatTip: Close other applications during benchmark runs for stable results. BenchmarkDotNet will report mean, median, and allocation statistics automatically.
# Convert between formats
dotnet run --project src/SharpImage.Cli -- convert photo.jpg photo.png
# Resize an image
dotnet run --project src/SharpImage.Cli -- resize photo.jpg -w 800 -h 600 resized.png
# Apply Gaussian blur
dotnet run --project src/SharpImage.Cli -- blur photo.jpg --sigma 3.0 blurred.png
# Composite two images
dotnet run --project src/SharpImage.Cli -- composite background.png overlay.png --mode multiply result.png
# Compare two images
dotnet run --project src/SharpImage.Cli -- compare original.png modified.png --diff difference.png
# Sharpen
dotnet run --project src/SharpImage.Cli -- sharpen photo.jpg --sigma 1.0 --amount 2.0 sharp.png
# See all commands
dotnet run --project src/SharpImage.Cli -- --helpOr publish AOT and use directly:
dotnet publish src/SharpImage.Cli -c Release
# Then use the native binary:
sharpimage convert photo.jpg photo.pngAdd a project reference to src/SharpImage/SharpImage.csproj:
using SharpImage.Image;
using SharpImage.Transform;
using SharpImage.Formats;
// Load an image
using var stream = File.OpenRead("photo.jpg");
var frame = JpegCoder.Read(stream);
// Resize with Lanczos3
var resized = Resize.Apply(frame, 800, 600, InterpolationMethod.Lanczos3);
// Save as PNG
using var output = File.Create("resized.png");
PngCoder.Write(resized, output);SharpImage/
├── src/
│ ├── SharpImage/ # Core library (DLL)
│ │ ├── Core/ # Quantum, PixelTypes, Geometry, MemoryPool
│ │ ├── Image/ # ImageFrame, PixelCache, CacheView, ImageList
│ │ ├── Colorspaces/ # 40+ colorspace converters
│ │ ├── Formats/ # 33 format coders (read/write)
│ │ ├── Transform/ # Resize, Crop, Rotate, Distort, SeamCarving
│ │ ├── Effects/ # 19 effect categories, 170+ operations
│ │ ├── Enhance/ # Equalize, Normalize, CLAHE, Curves, etc.
│ │ ├── Composite/ # 29 blend modes
│ │ ├── Analysis/ # Edge detection, hashing, segmentation
│ │ ├── Fourier/ # FFT forward/inverse
│ │ ├── Draw/ # Primitives, text, paths
│ │ ├── Morphology/ # Erode, Dilate, Skeleton, Hit-and-Miss
│ │ └── Channel/ # Channel operations, separation, combining
│ └── SharpImage.Cli/ # Command-line interface (228 commands)
├── tests/
│ └── SharpImage.Tests/ # 1,400+ tests (TUnit framework)
└── benchmarks/
└── SharpImage.Benchmarks/ # BenchmarkDotNet performance suite
| Type | Description |
|---|---|
ImageFrame |
Core image container. Holds pixel data, dimensions, colorspace, alpha channel info |
Quantum |
16-bit (ushort) quantum type. MaxValue = 65535, Scale = 1.0 / 65535 |
PixelCache |
Memory-mapped pixel storage with disk fallback for large images |
FormatRegistry |
Auto-detects and routes to the correct format coder |
- 16-bit quantum (ushort per channel) — matches ImageMagick's high-quality internal representation
- Row-major layout — pixels stored in contiguous rows for cache efficiency
- 3 or 4 channels — RGB or RGBA, interleaved per pixel
- Large image support — automatic disk-backed pixel cache for images exceeding memory limits
The test suite uses TUnit and covers:
- Format round-trips — encode→decode→compare for all 33 formats
- Colorspace accuracy — forward→inverse conversion for all 40+ colorspaces
- Transform correctness — pixel-perfect verification of flip, flop, rotate, crop, resize (all 23 methods)
- Edge cases — 1×1 images, 16384×1 strips, all-black/white, fully transparent, extreme resize ratios, odd/prime dimensions, 16-bit quantum extremes
- Effect coverage — each effect tested with multiple parameter combinations
- Composite math — blend mode output verified against manual calculations
Contributions are welcome. Please:
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Ensure all existing tests pass:
dotnet run --project tests/SharpImage.Tests -c Release - Run benchmarks to check for regressions:
dotnet run --project benchmarks/SharpImage.Benchmarks -c Release -- --filter *YourArea* - Submit a pull request
- PascalCase for public members, types, methods, properties
- camelCase for local variables and private fields
- Prefer
structoverclassfor small data types - Use
Span<T>andstackallocin hot paths - No dependency injection — direct static method calls
- Keep files focused but don't create separate files for small DTOs
Licensed under the Apache License 2.0.
- ImageMagick — the project that defined image processing for decades. SharpImage is a clean-room reimplementation inspired by ImageMagick's feature set and algorithms.
- TUnit — modern .NET test framework
- BenchmarkDotNet — precise .NET benchmarking
- Spectre.Console — beautiful CLI output