Skip to main content

JavaScript MRZ Scanner UI Components - SDK Features

The MRZ (Machine Readable Zone) Scanner is able to scan and decode the MRZ data on an ID card or passport.

alt text

Integrating the MRZ Scanner UI

Configuration

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

MrzScannerConfiguration inherits the base properties:

  • containerId – The id of the containing HTML element where the MRZ Scanner will be initialized. Required
  • 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. Optional

Additionally, ScanbotSDK MRZ Scanner has the following configurable options:

  • onMrzDetected – Your callback for receiving detection results. Required
  • accumulatedFrameVerificationConfiguration – Configures when a scan result should be considered verified, i.e. when it's verificationSuccessful property will be true. Optional. Should be set to an object with the following properties:
    • maximumNumberOfAccumulatedFrames: number – Maximum number of accumulated frames to inspect to verify a scan result. 3 by default.
    • minimumNumberOfRequiredFramesWithEqualRecognitionResult: number – Minimum number of accumulated frames that have an equal result. 2 by default.

The result of onMrzDetected is a MrzResult object that contains the following properties:

documentNumber?: MrzField;
issuingAuthority?: MrzField;
departmentOfIssuance?: MrzField;
givenNames?: MrzField;
surname?: MrzField;
nationality?: MrzField;
birthDate?: MrzField;
gender?: MrzField;
expiryDate?: MrzField;
personalNumber?: MrzField;
travelDocType?: MrzField;
travelDocTypeVariant?: MrzField;
optional1?: MrzField;
optional2?: MrzField;
discreetIssuingStateOrOrganization?: MrzField;
kindOfDocumentField?: MrzField;
documentType?: MrzField;
format?: MrzField;
pinCode?: MrzField;
languageCode?: MrzField;
versionNumber?: MrzField;
checkDigits?: MrzCheckDigits;
verificationSuccessful?: boolean;

MrzCheckDigits contains values of various check digit types as follows:

general?: MrzField;
documentNumber?: MrzField;
birthDate?: MrzField;
expiryDate?: MrzField;
personalNumber?: MrzField;

MrzField contains the following fields:

name?: string;
value?: string;
confidence?: number;
validated?: MRZFieldValidationStatus;

MRZFieldValidationStatus is a custom type:

type MRZFieldValidationStatus =
'Success'
| 'Failure'
| 'NotValidated';

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";
...

Opening the Scanner

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

const config = {
containerId: MRZ_SCANNER_CONTAINER,
onMrzDetected: onMrzDetected,
onError: onError
};

const scanner = await scanbotSDK.createMrzScanner(configuration);

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

API

To handle MRZ 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.

Disposal

As with the Document Scanner, the MRZ Scanner should also be properly disposed of when you have detected and processed the relevant MRZ:

await mrzScanner.dispose();

Detection on the Image

async createSimpleMRZRecognizer(): Promise<SimpleMrzRecognizer>

Example usage:

...
reader.readAsDataURL(file);

reader.onload = async (e) => {

const recognizer = await scanbotSDK.createSimpleMRZRecognizer();

const result = await recognizer.recognizeURL(reader.result);

this.onMrzDetected(result);

await recognizer.release();
};

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?