Skip to content

API reference

The whole public surface. Everything is nullable-annotated and documented in XML, so the same text appears in IntelliSense.

The component

<BbScanner> parameters

ParameterTypeDefaultPurpose
FormatsBbBarcodeFormatAllSymbologies to look for. A flags enum.
RegionBbScanRegionFullNormalized sub-rectangle to search.
OptionsBbScannerOptions?nullAdvanced tuning applied under Formats and Region.
TargetFrameRateint15Frames a second to decode.
RequestedWidth / Heightint1280 / 720Camera constraints; the browser may negotiate otherwise.
MaxProcessingSizeint640Longest edge of the image the decoder sees.
FacingBbCameraFacingRearPreferred camera when no device id is given.
DeviceIdstring?nullA specific camera to open.
AutoStartbooltrueOpen the camera as soon as the component is ready.
DuplicateSuppressionWindowTimeSpan?null (2s)How long an identical value stays suppressed. Set, it overrides Options; unset, Options decides, else 2 s.
ShowControlsbooltrueBuilt-in control bar.
ShowStatusBarbooltrueBuilt-in status bar.
ShowReticlebooltrueCorner reticle over the scan region.
ShowMaskbooltrueDim outside the scan region.
HighlightResultsbooltrueOutline a decoded symbol in place.
EnableFileScanningbooltrueOffer still image scanning.
FillboolfalseFill the parent instead of keeping the camera's aspect ratio.
AriaLabelstring"Barcode scanner"Accessible name for the region.
CssClassstring?nullExtra classes on the root element.
OverlayRenderFragment<BbScanner>?nullReplaces the reticle; receives the scanner.
MessageTemplateRenderFragment<string>?nullReplaces status and error message rendering.
ControlsContentRenderFragment?nullExtra controls in the built-in bar.
ChildContentRenderFragment?nullArbitrary content over the viewport.
@attributesany-Any other attribute is applied to the root element. A class or style given this way is merged with the component's own rather than replacing it.

<BbScanner> events

EventPayloadRaised when
OnScanBbBarcodeResultA symbol is decoded and passes duplicate suppression.
OnErrorBbScannerExceptionThe camera cannot start, or a frame fails.
OnStatusChangedBbScannerStatusThe lifecycle state changes.
OnCameraChangedBbCameraInfoA camera opens, with what was negotiated.
OnDiagnosticsBbScanDiagnosticsAt most twice a second, with frame timings.

<BbScanner> methods and properties

Task            StartAsync(string? deviceId = null)
Task            StopAsync()
void            Pause()
void            Resume()
Task            SwitchCameraAsync(string deviceId)
Task<bool>      SetTorchAsync(bool on)
Task<bool>      SetZoomAsync(double zoom)
Task            OpenFilePickerAsync()
Task<IReadOnlyList<BbCameraDevice>> GetCamerasAsync()
BbBarcodeResult?  DecodeImage(ReadOnlySpan<byte> pixels, int width, int height, BbPixelFormat format)

BbScannerStatus   Status
BbCameraInfo?     Camera
IReadOnlyList<BbCameraDevice> Cameras
BbScanDiagnostics Diagnostics
long            FramesDecoded
long            FramesWithSymbol
bool            IsTorchOn
double          Zoom
(int, int)      ProcessingSize

StartAsync is safe to call at any time: a call that arrives while an earlier one is still waiting for the permission prompt supersedes it, and the superseded request releases its camera rather than leaving it running. The same holds for StopAsync and for disposal, so navigating away mid-prompt never leaves the camera indicator lit.

The results and the options

BbBarcodeResult

MemberTypeMeaning
TextstringDecoded value after character set interpretation.
RawBytesReadOnlyMemory<byte>Payload bytes before interpretation.
FormatBbBarcodeFormatThe symbology that produced the value.
TimestampDateTimeOffsetWhen the frame was decoded.
CornersIReadOnlyList<BbScanPoint>Locator points in frame pixels.
BoundingBoxBbScanRectAxis aligned box around the corners.
FrameWidth / FrameHeightintSize of the frame the value came from.
MetadataBbBarcodeResultMetadata?Version, error correction level, corrections, ECI, GS1, structured append.

BbScannerOptions

BbBarcodeFormat Formats                    = BbBarcodeFormat.All
BbScanRegion    Region                     = BbScanRegion.Full
int           MaxScanLines               = 15      // lines per orientation
int           DownsampleFactor           = 1
bool          TryHarder                  = false   // exhaustive detection, full rotation sweep
bool          AllowInverted              = false   // light on dark symbols
bool          TryReversedRows            = true    // linear symbols read right to left
bool          TryVerticalLines           = true    // columns and tilted lines, for rotated symbols
IReadOnlyCollection<int> ItfLengths      = 6..20 even
bool          Code39CheckDigit           = false   // require the modulo 43 check character
bool          Code39ExtendedMode         = false   // interpret Code 39 as full ASCII
TimeSpan      DuplicateSuppressionWindow = 2 seconds

BbScannerOptions.ForStillImages()   // 60 scan lines, TryHarder, AllowInverted, no suppression
options.Clone()                   // take a copy before editing a running scanner's options
options.Validate()                // throws on an out of range value

ITF has no check character, so ItfLengths is the main defence against a truncated symbol being reported as a shorter, structurally valid number. Narrow it to the lengths your application actually uses.

The decoder

Headless use

The decoding pipeline has no dependency on Blazor or on a browser. It runs anywhere .NET runs, which is what makes it testable and benchmarkable.

using var decoder = new BbBarcodeDecoder(new BbScannerOptions
{
    Formats = BbBarcodeFormat.QrCode | BbBarcodeFormat.DataMatrix,
    DuplicateSuppressionWindow = TimeSpan.Zero,
});

var result = decoder.Decode(rgbaPixels, width, height, BbPixelFormat.Rgba32);
if (result is not null)
{
    Console.WriteLine($"{result.Format}: {result.Text}");
    Console.WriteLine($"took {decoder.LastFrame.Total.TotalMilliseconds:0.00} ms");
}

Extending the decoder

A new symbology implements IBbRowDecoder for a linear code or IBbMatrixDecoder for a two dimensional one. Both receive already binarised input, so a new reader only has to contribute its own character table and structure.

public interface IBbRowDecoder
{
    BbBarcodeFormat Formats { get; }
    BbSymbolDecodeResult? DecodeRow(int rowNumber, BbBitRow row, BbBarcodeFormat enabledFormats);
}

public interface IBbMatrixDecoder
{
    BbBarcodeFormat Formats { get; }
    BbSymbolDecodeResult? Decode(BbBitMatrix image, BbMatrixDecodeOptions options);
}

Binarisation is an extension point too: IBbBinarizer has one implementation tuned for matrix codes and one for linear rows, and a replacement can be substituted for either.

An unhandled error has occurred. Reload 🗙