Skip to main content

Barcode Scanner | Web Document Scanner

Scanbot WebSDK also features the option to scan and detect various barcodes.

Barcode Scanner UI

Opening the Scanner

To open the Barcode Scanner, simply call the relevant SDK function with the configuration object:

const scanner = await scanbotSDK.createBarcodeScanner(configuration);

You should store the barcode scanner object in a globally accessible location, as additional barcode scanner actions are functions of that object.

Disposal

The Barcode Scanner should also be properly disposed of when you have detected and processed the relevant barcodes:

dispose(): void;

Configuration

ScanbotSDK Barcode Scanner takes an instance of BarcodeScannerConfiguration as its argument. This is your main object for configuration options, styling and receiving the results.

    let scanner;
const configuration = {
// The `id` of the containing HTML element where the Barcode Scanner will be initialized.
containerId: 'scanner',
onBarcodesDetected: (result: BarcodeResult) => {
// If you're happy with the result, dispose the scanner right away
scanner.dispose();
// Otherwise the scanner will continue scanning and delivering results
const format = result.barcodes[0].format // The barcode's symbology
const text = result.barcodes[0].text // The text value of the barcode
// ...
}
}
scanner = await scanbotSDK.createBarcodeScanner(configuration);

BarcodeScannerConfiguration requires the following parameters:

  • containerId – The id of the containing HTML element where the Barcode Scanner will be initialized
  • onBarcodesDetected – Your callback for receiving detection results

BarcodeScannerConfiguration also inherits the following optional base properties:

  • videoConstraints – The desired video resolution. Optional, defaults to 1920x1080
  • mirrored - Whether the screen should be mirrored. Useful when using a user-facing camera. false by default
  • preferredCamera - Camera label or camera device id. If not available, a default camera is used as fallback
  • onError – Callback when something went wrong.

Additionally, ScanbotSDK Barcode Scanner has the following configurable options:

  • showFinder - An optional boolean to determine if the scanner should start with the viewfinder rectangle enabled
  • barcodeFormats - An array which is used to specify the enabled barcode formats
  • captureDelay – The delay between receiving detection results. In milliseconds. Defaults to 1000
  • returnBarcodeImage - An optional boolean to determine if the scanner should return the JPEG image of a recognized barcode (as an ArrayBuffer). Defaults to false
  • engineMode - The engine mode of the barcode recognizer. Defaults to 'NEXT_GEN'. To use legacy recognizer, please specify 'LEGACY'.

It is necessary to pass MSI_PLESSEY in barcodeFormats to be able to scan MSI Plessey barcodes. The following snippet shows the available formats:

[
"AZTEC",
"CODABAR",
"CODE_39",
"CODE_93",
"CODE_128",
"DATA_MATRIX",
"EAN_8",
"EAN_13",
"ITF",
"MAXICODE",
"PDF_417",
"QR_CODE",
"RSS_14",
"RSS_EXPANDED",
"UPC_A",
"UPC_E",
"UPC_EAN_EXTENSION",
"MSI_PLESSEY"
]

The result of onBarcodesDetected is a BarcodeResult object that contains the following properties:

barcodes: Barcode[];

The list will always contain at least one element. No empty result is returned.

A barcode item contains the following properties:

  • format: BarcodeFormat – The type of barcode. One of the types listed in the previous paragraph.
  • text: string – The data contained in the barcode.
  • rawBytes: Uint8Array – The same data contained in the barcode. Can be disregarded in most scenarios, useful when the result is binary data, not a string.
  • barcodeImage: Uint8Array – The image of the recognized barcode if returnBarcodeImage in BarcodeScannerConfiguration is set to true.
  • parsedText – If the data is structured and parsing is supported for the data type, this structured data will be parsed into document-like data structures.

Styling

ViewFinder-based scanners all have the following two top-level configuration properties:

finder?: ViewFinderConfiguration;
userGuidance?: UserGuidanceConfiguration;

finder

The finder property controls the styling of the background and the hole, and its style property can be of either FinderCorneredStyle or FinderStrokedStyle (defaults to FinderCorneredStyle).

Both of them have the following properties and default values:

/** Color of the viewfinder corner's outlines. @defaultValue "#FFFFFFFF"; */
public strokeColor: string = "#FFFFFFFF";
/** Width of the viewfinder corner's outlines. @defaultValue 3.0; */
public strokeWidth: number = 3.0;
/** Radius of the viewfinder's corners. @defaultValue 10.0; */
public cornerRadius: number = 10.0;

If you're configuring the scanner from a JSON Object, be sure to include the type name:

finder: {
style: {
_type: "FinderStrokedStyle",
}
},

Your entire finder configutation object might look something like this:

const config = {
...
finder: {
visible: true,
style: {
_type: "FinderStrokedStyle",
cornerRadius: 50,
strokeColor: "green",
strokeWidth: 5,
},
aspectRatio: {
width: 16,
height: 9,
},
overlayColor: "rgba(0, 0, 0, 0.5)",
} as ViewFinderConfiguration
};

Alternatively, you can configure the object line-by-line:

config.finder!.style._type = "FinderStrokedStyle";
config.finder!.style.cornerRadius = 20;
...

userGuidance

The userGuidance property is for styling the hint text below the finder window and has the following options:

    /** Whether the user guidance is visible. @defaultValue true; */
public visible: boolean = true;
/** Title of the user guidance. @defaultValue new StyledText({ "color": "?sbColorOnPrimary" }); */
public title: StyledText = new StyledText({ "color": "?sbColorOnPrimary" });
/** Background style used for the user guidance.
@defaultValue new BackgroundStyle({
"strokeColor": "#00000000",
"fillColor": "?sbColorSurfaceLow"
});
*/
public background: BackgroundStyle = new BackgroundStyle({ "strokeColor": "#00000000", "fillColor": "?sbColorSurfaceLow" });

Your entire userGuidance configutation object might look something like this:

const config = {
...
userGuidance: {
visible: true,
title: {
text: "Scan item",
color: "white",
},
background: {
strokeColor: "green",
fillColor: "rgba(0, 255, 0, 0.2)",
}
} as UserGuidanceConfiguration
};

Alternatively, you can also configure the object line-by-line:

config.userGuidance!.title.text = "Scan item";
config.userGuidance!.title.color = "white";
...

API

To handle barcode results (avoid duplicate scans etc), ScanbotSDK offers the following convenient methods to pause and resume detection while you are processing the data on your side:

resumeDetection(): void;
pauseDetection(): void;
isDetectionPaused(): boolean;

Switching between the front and rear camera

swapCameraFacing(force?: boolean): void;

swapCameraFacing(true) indicates that only the swapped camera (e.g. front camera) is acceptable; if the swapped camera is not available, or the user declines the permission to use that camera, the media request will fail.

danger

Firefox on Android: Due to current Firefox browser limitations, we highly recommend checking the running browser and disabling this feature for Firebox browsers.

Switching to a specific available camera

fetchAvailableCameras(): Promise<CameraInfo[]>;
switchCamera(deviceId: string, mirrored?: boolean): void;
getActiveCameraInfo(): CameraInfo | undefined;
interface CameraInfo {
deviceId: string;
label: string;
facingMode?: CameraFacingMode;
supportsTorchControl?: boolean;
}

type CameraFacingMode = 'front' | 'back' | 'unknown';

You can search for available cameras on the running browser by using fetchAvailableCameras method of a scanner. You can retrieve the label, device id and the camera facing mode information of the active camera of a scanner by using getActiveCameraInfo method. And, you can switch to another available camera by utilizing its device id, by using switchCamera method.

const cameras = await scanner.fetchAvailableCameras()
if (cameras) {
const currentCameraInfo = scanner.getActiveCameraInfo();
if (currentCameraInfo) {
const cameraIndex = cameras.findIndex((cameraInfo) => { return cameraInfo.deviceId == currentCameraInfo.deviceId });
const newCameraIndex = (cameraIndex + 1) % (cameras.length);

scanner.switchCamera(cameras[newCameraIndex].deviceId);
}
}

Controlling the torch (flashlight)

On some mobile devices, the browser can control the torch (flashlight). Check scanner.getActiveCameraInfo().supportsTorchControl to see if the browser can control the torch for the currently active camera. If true, you can control the torch by using the setTorchState method of the scanner.

setTorchState(state: boolean): Promise<void>;
info

On Android devices, only Chrome supports torch control. Starting with iOS 17.4, all supported browsers on iOS offer torch control functionality.

Scan and Count

ScanbotSDK Barcode Scanner also features a special and custom user interface that will detect barcodes from a single snapshot and display the result in a unique manner. This feature uses the greatest resolution available and offers the most precise scan possible.

To enable this feature, simply enable the property in the configuration, as follows:

scanAndCount: {
enabled: true,
style: {
// Add custom styling to the RTU component
}
}

While using the finder view in this mode is possible, it works best when you disable the finder and allow full-screen captures:

showFinder: false

Results are returned normally and continuously via your onBarcodesDetected. Please note that results are returned for each consecutive scan, not only after the last scan.

AR Overlay

The Barcode AR Overlay can be enabled to display and select recognized barcodes in an augmented-reality fashion. Each recognized barcode will be presented on the barcode overlay by a colored frame and text. Tapping on one of the barcodes will deliver this barcode as a result to the delegate of the barcode scanner. These tapped/delivered barcodes can be highlighted with a different color. The text for each barcode is customizable.

Displaying an extra layer of information in the live view is useful in a range of scanning use cases.

To enable the AR Overlay, simply enable the property in the configuration, as follows:

overlay: {
visible: true,
}

Additional configurable properties of the overlay feature are as follows:

overlay: {
// Determines whether the selection overlay should be automatically selected
// (and when onBarcodeDetected is called) when a barcode is detected. Defaults to false
automaticSelectionEnabled: false,
// Controls the format of the text displayed below the selection overlay. Defaults to just the code value
textFormat: SelectionOverlayTextFormat.Text,
}

In essence, automaticSelectionEnabled, means there that there are two modes available:

  • AR - MultiScan allows users to quickly scan multiple barcodes without manually selecting each one.
  • AR - SelectScan allows users to selectively scan barcodes by tapping on them.

A third mode can be enabled as well:

  • AR - FindAndPick allows users to locate specific items in a large inventory by pre-defining their value.

In order to implement this mode, onBarcodeFound callback should be overridden to apply custom styling to overlays before they are rendered. The following snippet demonstrates just that, specifically, how to display QR Codes, and only QR Codes, with a yellow overlay:

overlay: {
onBarcodeFound: (code: Barcode, polygon: IBarcodePolygonHandle, label: IBarcodePolygonLabelHandle) => {
if (code.format === "QR_CODE") {
polygon.style({ fill: "rgba(255, 255, 0, 0.3)", stroke: "yellow" })
}
}
}

Additionally, the overlay has the following styling options:

overlay: {
style: {
polygonStrokeColor: "rgba(255, 0, 0, 1)";
polygonFillColor: "rgba(255, 0, 0, 0.3)";
highlightedPolygonStrokeColor: "rgba(0, 255, 0, 1)";
highlightedPolygonFillColor: "rgba(0, 255, 0, 0.3)";

textColor: "white";
textBackgroundColor: "rgba(255, 0, 0, 0.9)";
highlightedTextColor: "white";
highlightedTextBackgroundColor: "rgba(0, 255, 0, 0.9)";
},

Want to scan longer than one minute?

Generate a free trial license to test the Scanbot SDK thoroughly.

Get your free Trial License

What do you think of this documentation?