Getting Started
Four concrete scenarios, each ~3 minutes.
Install
Section titled “Install”dotnet add package Pragmatic.ImagingThe NuGet includes the native pragmatic_native binary for supported RIDs. See native-deployment.md for the platform matrix.
Scenario 1 — resize and convert
Section titled “Scenario 1 — resize and convert”Load a JPEG, resize to thumbnail dimensions, convert to WebP.
using Pragmatic.Imaging;
using var pipe = ImagePipeline.Load(File.ReadAllBytes("photo.jpg"));
using var output = File.Create("photo-thumb.webp");pipe.Thumbnail(maxWidth: 400, maxHeight: 400) .EncodeTo(output, ImageFormat.Webp, quality: 80);Thumbnail preserves aspect ratio and fits the longest side within the bounding box. For an exact fixed size, use Resize(width, height).
Scenario 2 — apply filters
Section titled “Scenario 2 — apply filters”Convert a photo to a grayscale sharpened version.
using var pipe = ImagePipeline.Load(bytes);
pipe.Grayscale() .Sharpen(sigma: 1.5f, threshold: 2) .Brightness(10) // nudge brighter .Contrast(1.1f) .EncodeTo(output, ImageFormat.Png);See operations.md for all filter parameters.
Scenario 3 — inspect an upload before decoding
Section titled “Scenario 3 — inspect an upload before decoding”A user uploads an image. Validate dimensions and format before running anything expensive.
using Pragmatic.Imaging;
using var upload = Request.Body;var info = ImageInfo.FromStream(upload, maxBytes: 65_536);
if (info.Width > 8000 || info.Height > 8000) return BadRequest("Image too large");
if (info.Format is not (ImageFormat.Jpeg or ImageFormat.Png or ImageFormat.Webp)) return BadRequest("Unsupported format");
upload.Position = 0; // ImageInfo only read the headerusing var pipe = ImagePipeline.Load(upload, new ImagingOptions{ MaxWidth = 8000, MaxHeight = 8000, AllowedFormats = ImageFormat.Jpeg | ImageFormat.Png | ImageFormat.Webp,});
// ... proceed with processingImageInfo.FromStream reads only enough of the stream to identify the header — typically the first few KB. The caller is responsible for rewinding the stream before decoding.
Scenario 4 — batch thumbnailing
Section titled “Scenario 4 — batch thumbnailing”Process a folder of images with bounded concurrency.
using Pragmatic.Imaging;
var inputs = Directory.GetFiles("photos", "*.jpg");var batch = new ImageBatch(maxConcurrency: 4);
await batch.ProcessAsync(inputs, async (path, ct) =>{ var bytes = await File.ReadAllBytesAsync(path, ct); using var pipe = ImagePipeline.Load(bytes);
var thumbPath = Path.ChangeExtension(path, ".thumb.webp"); using var output = File.Create(thumbPath); pipe.Thumbnail(256, 256).EncodeTo(output, ImageFormat.Webp, quality: 75);});ImageBatch.ProcessAsync caps how many pipelines are alive at once — adjust maxConcurrency based on the memory ceiling you can afford. On a typical server, 4-8 is a safe starting point.
Scenario 5 — generate a QR code
Section titled “Scenario 5 — generate a QR code”No pipeline needed — QR generation is a direct call.
using var output = File.Create("qr.png");QrCode.GeneratePng( text: "https://pragmaticdesign.net", output: output, moduleSize: 10, margin: 2);moduleSize is the pixel size of each QR module; margin is the quiet zone in modules. The output is always PNG — thread-safe, no options object needed.
Beyond the five scenarios
Section titled “Beyond the five scenarios”Applying safety options everywhere
Section titled “Applying safety options everywhere”Always pass ImagingOptions for untrusted input:
var safe = new ImagingOptions{ MaxWidth = 4096, MaxHeight = 4096, MaxDecodedBytes = 100 * 1024 * 1024, AllowedFormats = ImageFormat.Jpeg | ImageFormat.Png | ImageFormat.Webp,};
using var pipe = ImagePipeline.Load(userUpload, safe);Defaults are conservative but not adversarial-hardened — configure for your workload.
Async streaming
Section titled “Async streaming”For HTTP responses, pipe directly to the response body:
[HttpGet("/thumbnail")]public async Task ThumbnailAsync(CancellationToken ct){ var bytes = await GetImageAsync(ct); using var pipe = ImagePipeline.Load(bytes); Response.ContentType = "image/webp"; pipe.Thumbnail(400, 400).EncodeTo(Response.Body, ImageFormat.Webp);}Runnable samples
Section titled “Runnable samples”Pragmatic.Imaging.Samples— QR / image info / resize / format / filters / crop / rotate / flip / chained transforms
- Operations reference — full method catalogue with parameters and semantics
- Native deployment — platforms, AOT, Docker notes
- Concepts — architecture, thread safety, error model