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 andrelease()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