我正在使用谷歌的ML Kit进行条形码扫描,并从谷歌提供的示例和教程中收集了下面的代码。然而,性能非常低下;需要几秒钟,可以是10、15秒,才能识别出一个条形码。是否有任何方法可以改善这种情况?
此外,如何用于反转的条形码?我发现需要反转图像,但如果在分析器中尝试获取image.bitmapInternal或image.byteBuffer,则始终为null。
Build.gradle
implementation 'com.google.mlkit:barcode-scanning:17.0.0'
// CameraX core library using camera2 implementation
implementation "androidx.camera:camera-camera2:1.0.2"
// CameraX Lifecycle Library
implementation "androidx.camera:camera-lifecycle:1.0.2"
// CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha31"
然后,在一个片段中:
typealias BarCodeListener = (barCode: String) -> Unit
const val TAG = "ConnectorScanner"
[...]
override fun onResume() {
super.onResume()
cameraExecutor = Executors.newSingleThreadExecutor()
startCamera()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
val resolution = Size(720, 1280)
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.setTargetResolution(resolution)
.build()
.also {
it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
}
imageCapture = ImageCapture.Builder()
.setTargetResolution(resolution)
.setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY)
.build()
val imageAnalyzer = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
.also {
it.setAnalyzer(cameraExecutor, BarCodeAnalyzer { barCode ->
if (BuildConfig.DEBUG) {
Toast.makeText(context, "Code: $barCode", Toast.LENGTH_LONG).show()
}
viewModel.onConnectorCodeScanned(barCode)
cameraProvider.unbindAll()
})
}
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture, imageAnalyzer
)
} catch (exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
showErrorDialog()
}
}, ContextCompat.getMainExecutor(requireContext()))
}
图像分析器
private class BarCodeAnalyzer(private val listener: BarCodeListener) : ImageAnalysis.Analyzer {
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(
Barcode.FORMAT_DATA_MATRIX
)
.build()
@SuppressLint("UnsafeOptInUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image
mediaImage?.let {
val image =
InputImage.fromMediaImage(it, imageProxy.imageInfo.rotationDegrees)
val scanner = BarcodeScanning.getClient(options)
scanner.process(image)
.addOnSuccessListener { barcodes ->
if (barcodes.isNotEmpty()) {
barcodes.firstOrNull()?.rawValue?.let { barcode ->
Log.d(TAG, barcode)
listener(barcode)
}
imageProxy.close()
}
}
}
imageProxy.close()
}
}