Converting Frame Data to an Image

Defined in package com.scandit.datacapture.core.data

When processing scanned barcodes or other data capture results, you may need to convert the frame data provided in callbacks to a platform-native image for display or storage. This guide shows how to convert FrameData to UIImage on iOS and Bitmap on Android.

Overview

The ImageBuffer class provides a ImageBuffer.toBitmap() method that converts the frame data to an Android Bitmap. This handles the YUV-to-RGB conversion internally.

Basic Usage

Access the bitmap from any data capture listener that provides frame data:

override fun onBarcodeScanned(
    sparkScan: SparkScan,
    session: SparkScanSession,
    frameData: FrameData?
) {
    val barcode = session.newlyRecognizedBarcode ?: return

    frameData?.let { data ->
        data.retain()

        val bitmap: Bitmap = try {
            data.imageBuffer.toBitmap()
        } finally {
            data.release()
        }

        // Use the bitmap (display in UI, save to disk, etc.)
        runOnUiThread {
            imageView.setImageBitmap(bitmap)
        }
    }
}

Note

Always call retain() before accessing frame data and release() when done, even for synchronous usage. Frame data is recycled when the callback returns.

Asynchronous Processing

When processing the frame on a background thread, call retain() before leaving the callback and release() when done:

override fun onBarcodeScanned(
    sparkScan: SparkScan,
    session: SparkScanSession,
    frameData: FrameData?
) {
    val barcode = session.newlyRecognizedBarcode ?: return

    frameData?.let { data ->
        // Retain before moving to a background thread
        data.retain()

        coroutineScope.launch(Dispatchers.IO) {
            val bitmap: Bitmap = try {
                data.imageBuffer.toBitmap()
            } finally {
                // Always release the frame data when done
                data.release()
            }

            withContext(Dispatchers.Main) {
                imageView.setImageBitmap(bitmap)
            }
        }
    }
}

Always pair retain() with release() in a try-finally block to prevent memory leaks.

Saving to Disk

Once you have a Bitmap (obtained via retain()/toBitmap()/release() as shown above), you can save it:

val file = File(cacheDir, "captured_frame.jpg")
file.outputStream().use { out ->
    bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out)
}

Important Notes

  • The ImageBuffer.toBitmap() method performs a format conversion, which can be expensive. Process images on a background thread.

  • Always call retain() before asynchronous processing and release() when done.

  • Resize bitmaps to the minimum size you need to reduce memory usage.

  • Recycle bitmaps with bitmap.recycle() when no longer needed.

See Also

  • FrameData – Interface for accessing frame data

  • ImageBuffer – Image buffer with conversion methods

  • ImagePlane – Individual image plane within a buffer