Skip to main content

Scanning a machine-readable zone from an image | Android Document Scanner

The Scanbot SDK MRZ Scanner can detect and extract information from still images imported from the gallery or any other source, not just live MRZ code detection.


The Example Apps are available to see the MRZ scanner in action and to gain a comprehensive understanding of how to integrate it into your project:

Add Feature as a Dependency

To use MRZScanner, add the following dependency for SDK Package 2 and the corresponding assets:


Initialize the SDK

Before use, the Scanbot SDK must be initialized. Add the following code snippet to your Application class:

import io.scanbot.sdk.ScanbotSDKInitializer

class ExampleApplication : Application() {

override fun onCreate() {

// Initialize the Scanbot Scanner SDK:
.license(this, licenseKey)
// TODO: other configuration calls

Processing the Image

To select an image from the photo library and run detection on it, a class for an image import contract is created using the modern Android result API.

class ImportImageContract(private val context: Context) : ActivityResultContract<Unit, Bitmap?>() {
override fun createIntent(context: Context, input: Unit): Intent {
// An image is selected from the photo library and document detection is run on it:
val imageIntent = Intent()
imageIntent.type = "image/*"
imageIntent.action = Intent.ACTION_GET_CONTENT
imageIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, false)
imageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false)

return Intent.createChooser(imageIntent, "Select a picture")

private fun processGalleryResult(data: Intent): Bitmap? {
val imageUri =
return MediaStore.Images.Media.getBitmap(context.contentResolver, imageUri)

override fun parseResult(resultCode: Int, intent: Intent?): Bitmap? {
return if (resultCode == Activity.RESULT_OK && intent != null) {
return processGalleryResult(intent)
} else {

To run the gallery call and get a Bitmap using ImportImageContract, the following code is used:

 val galleryImageLauncher =
registerForActivityResult(ImportImageContract(this)) { resultEntity ->
lifecycleScope.launch(Dispatchers.Default) {
val activity = this@MainActivity
val sdk = ScanbotSDK(activity)
if (!sdk.licenseInfo.isValid) {
withContext(Dispatchers.Main) {
"License has expired!",
} else {
resultEntity?.let { bitmap ->
// Image processing is carried out
// processImage()
findViewById<View>( {

Create a Scanner

val scanbotSDK = ScanbotSDK(this)
val mrzScanner = scanbotSDK.createMrzScanner()

Avoid creating new MRZScanner instances for each import operation as this will also allocate memory for each instance.


Use the Scanbot SDK to detect the desired element on the imported bitmap.

private fun processImage(mrzScanner: MRZScanner, bitmap: Bitmap) {
val mrzRecognitionResult = mrzScanner.recognizeMRZBitmap(bitmap, 0)
// Proceed MRZ recognition result
// processResult(result)

Want to scan longer than one minute?

Generate your free "no-strings-attached" Trial License and properly test the Scanbot SDK.

Get your free Trial License

What do you think of this documentation?