Batch processing
The same pipeline over many files with bounded concurrency, live progress, cancellation, and a per-file result rather than one failure aborting the run. This is the headless batch API driving a UI, not a separate code path.
Try it
Pipeline
The batch API
ProcessBatchAsync is on ImageProcessor, which in a browser comes from
ImageProcessorFactory.GetAsync() once the codec probe has run; on a server,
AddBitBmageHeadlessServices registers it directly. Every item comes back with its
own outcome - Output, Error or WasCancelled - and
StopOnFirstError is opt-in.
var processor = await processorFactory.GetAsync();var result = await processor.ProcessBatchAsync(items, pipeline, new BatchOptions{ MaxConcurrency = 2, StopOnFirstError = false, // one bad file must not lose the rest ExportOptions = exportOptions, Progress = new Progress<BatchProgress>(p => { completed = p.Completed; if (p.Last.Error is { } error) Log(p.Last.FileName, error); }),}, cancellationToken);foreach (var item in result.Succeeded) Save(item.Output!);foreach (var item in result.Failed) Report(item.FileName, item.Error!);
Size MaxConcurrency against memory, not cores: four workers on 24 megapixel
photos is roughly 400 MB of live pixels. Two is a safe default on phones.