loading

The headless API

Not a single component on this page uses the editor. Everything below is the same engine driven from plain C#, which is how you would use it in an upload handler, a thumbnail service, or a console tool.

Run every example

No browser at all

The same packages work in an ASP.NET Core endpoint or a console app. Register the headless services and you get the managed PNG, JPEG, BMP and GIF codecs with no JavaScript involved - and ImageProcessor directly, because the managed codecs need no probing. Asking for WebP there throws ImageCapabilityException saying so.

C#
// Program.cs of an API that accepts uploadsbuilder.Services.AddBitBmageHeadlessServices(o => o.Limits = ImageLimits.Default);​// In the endpointapp.MapPost("/upload", async (IFormFile file, ImageProcessor processor) =>{    // Cap the upload before reading it; IFormFile reports its length up front.    if (file.Length > 20 * 1024 * 1024) return Results.BadRequest("Too large.");    using var buffer = new MemoryStream();    await file.CopyToAsync(buffer);    var bytes = buffer.ToArray();​    // Reject before decoding anything.    var info = processor.Identify(bytes);    if (info is null) return Results.BadRequest("Not a supported image.");    if ((long)info.Width * info.Height > 30_000_000) return Results.BadRequest("Too large.");​    var thumb = await processor.ProcessAsync(        bytes,        ImagePipeline.Create().AutoOrient().MaxSize(400, 400),        new ImageExportOptions { Format = ImageFormat.Jpeg, Quality = 0.8 });​    return Results.File(thumb.Data, thumb.MimeType);});

The pieces

TypePurpose
ImageBufferThe pixels. Pooled; dispose it.
ImagePipelineAn immutable list of operations - see Pipelines.
ImageProcessorDecode, process, encode and batch. Registered directly by AddBitBmageHeadlessServices; in a browser app, get one from ImageProcessorFactory.GetAsync().
ImageCanvasImmediate-mode drawing.
ImageCodecRegistryWhich decoders and encoders are available; register your own to take precedence.
ImageDocumentA non-destructive edit: pipeline plus annotations.
DocumentRendererRenders a document against a source image.
EditHistoryUndo and redo over documents.
FontTextRasterizerText from a font file, no browser needed.

Drawing without a UI

ImageCanvas is a complete drawing surface - the last example above was composed with it. Paths come from PathBuilder (lines, quadratic and cubic curves, arcs, rounded rectangles, ellipses, polygons, flattened adaptively), and fills take a colour or any IPaint: solid, linear and radial gradients, or your own.

C#

Text needs a rasterizer. In a browser, BrowserTextRasterizer uses the platform's text engine (shaping, emoji, right-to-left). Anywhere else, FontTextRasterizer draws from a TrueType or OpenType font with glyf outlines - kerning and word wrapping included, complex shaping not.

C#

Analysing an image

ImageStatistics samples on a regular grid by default, which keeps a 24 megapixel photo well under a frame while staying indistinguishable from a full pass. The dominant colours on the Avatar page come from here.

C#

ImagePlaceholder is the low-quality image placeholder pattern: a 67 character token for a 4×4 grid, small enough to return from a list endpoint, that renders the right colours and shape immediately - as pixels, or as CSS gradients alone.

C#

Non-destructive editing without the editor

The editor's document model is public. A document is a value: serialise it, send it to a server, or apply it to a different image - rendering never modifies the source.

C#
var document = ImageDocument.Create(source)    .AddOperation(new CropOperation(100, 100, 800, 600))    .AddOperation(new BrightnessAdjustment(0.1f))    .AddAnnotation(new ArrowAnnotation { Start = a, End = b });​var history = new EditHistory(document);history.Push(document.AddAnnotation(label), "Add label");history.Undo();​using var rendered = new DocumentRenderer(textRasterizer)    .Render(history.Current, source);
An unhandled error has occurred. Reload 🗙