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.
// 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
| Type | Purpose |
|---|---|
ImageBuffer | The pixels. Pooled; dispose it. |
ImagePipeline | An immutable list of operations - see Pipelines. |
ImageProcessor | Decode, process, encode and batch. Registered directly by AddBitBmageHeadlessServices; in a browser app, get one from ImageProcessorFactory.GetAsync(). |
ImageCanvas | Immediate-mode drawing. |
ImageCodecRegistry | Which decoders and encoders are available; register your own to take precedence. |
ImageDocument | A non-destructive edit: pipeline plus annotations. |
DocumentRenderer | Renders a document against a source image. |
EditHistory | Undo and redo over documents. |
FontTextRasterizer | Text 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.
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.
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.
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.
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.
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);