当前位置: 首页 > 知识库问答 >
问题:

一些设备上最新的CameraX和条形码扫描的问题

经嘉
2023-03-14
 def camerax_version = "1.0.0-beta11"
    implementation "androidx.camera:camera-core:${camerax_version}"
    implementation "androidx.camera:camera-camera2:${camerax_version}"
    implementation "androidx.camera:camera-lifecycle:${camerax_version}"
    implementation "androidx.camera:camera-view:1.0.0-alpha18"
    implementation "androidx.camera:camera-extensions:1.0.0-alpha18"
    implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'
class ScanQRCameraViewHandler(
    private val fragment: ScanQRDialogFragment,
    private val previewView: PreviewView
) {
    private val displayLayout get() = previewView
    companion object {
        private const val RATIO_4_3_VALUE = 4.0 / 3.0
        private const val RATIO_16_9_VALUE = 16.0 / 9.0
    }

    private val analyzer = GMSMLKitAnalyzer(onFoundQR = { extractedString ->
        fragment.verifyExtractedString(extractedString)
    }, onNotFoundQR = {
        resetStateToAllowNewImageStream()
    })
    private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
    private var camera: Camera? = null
    private var isAnalyzing = false

    internal fun resetStateToAllowNewImageStream() {
        isAnalyzing = false
    }

    internal fun setTorceEnable(isEnabled: Boolean) {
        camera?.cameraControl?.enableTorch(isEnabled)
    }

    internal fun initCameraProviderIfHasNot() {
        if (cameraProviderFuture == null) {
            fragment.context?.let {
                cameraProviderFuture = ProcessCameraProvider.getInstance(it)
                val executor = ContextCompat.getMainExecutor(it)
                cameraProviderFuture?.addListener({
                    bindPreview(cameraProviderFuture?.get(), executor)
                }, executor)
            }
        }
    }

    private fun bindPreview(cameraProvider: ProcessCameraProvider?, executor: Executor) {
        val metrics = DisplayMetrics().also { displayLayout.display.getRealMetrics(it) }
        val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)

        val preview = initPreview(screenAspectRatio)
        val imageAnalyzer = createImageAnalyzer()
        val imageAnalysis = createImageAnalysis(executor, imageAnalyzer, screenAspectRatio)
        val cameraSelector = createCameraSelector()

        cameraProvider?.unbindAll()
        camera = cameraProvider?.bindToLifecycle(
            fragment as LifecycleOwner,
            cameraSelector, imageAnalysis, preview
        )
    }

    private fun createCameraSelector(): CameraSelector {
        return CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()
    }

    private fun createImageAnalysis(
        executor: Executor, imageAnalyzer: ImageAnalysis.Analyzer, screenAspectRatio: Int
    ): ImageAnalysis {
        val rotation = displayLayout.rotation
        val imageAnalysis = ImageAnalysis.Builder()
//            .setTargetRotation(rotation.toInt())
//            .setTargetAspectRatio(screenAspectRatio)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()

        imageAnalysis.setAnalyzer(executor, imageAnalyzer)
        return imageAnalysis
    }

    private fun createImageAnalyzer(): ImageAnalysis.Analyzer {
        return ImageAnalysis.Analyzer {
            isAnalyzing = true
            analyzer.analyze(it)
        }
    }

    private fun initPreview(screenAspectRatio: Int): Preview {

        val preview: Preview = Preview.Builder()
            //.setTargetResolution(Size(840, 840))
          //  .setTargetAspectRatio(screenAspectRatio)
          //  .setTargetRotation(displayLayout.rotation.toInt())
            .build()
        preview.setSurfaceProvider(previewView.surfaceProvider)
        return preview
    }

    fun unbindAll() {
        cameraProviderFuture?.get()?.unbindAll()
    }


    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = width.coerceAtLeast(height).toDouble() / width.coerceAtMost(height)
        if (kotlin.math.abs(previewRatio - RATIO_4_3_VALUE) <= kotlin.math.abs(previewRatio - RATIO_16_9_VALUE)) {
            return AspectRatio.RATIO_4_3
        }
        return AspectRatio.RATIO_16_9
    }
}
internal class GMSMLKitAnalyzer(
    private val onFoundQR: (String) -> Unit,
    private val onNotFoundQR: () -> Unit
) :
    ImageAnalysis.Analyzer {

    private val options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(Barcode.FORMAT_QR_CODE).build()

    @SuppressLint("UnsafeExperimentalUsageError")
    override fun analyze(imageProxy: ImageProxy) {
        imageProxy.image?.let { mediaImage ->
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
            val scanner = BarcodeScanning.getClient(options)
            CoroutineScope(Dispatchers.Main).launch {
                val result = scanner.process(image).await()
                result.result?.let { barcodes ->
                    barcodes.find { it.rawValue != null }?.rawValue?.let {
                        onFoundQR(it)
                    } ?: run { onNotFoundQR() }
                }
                imageProxy.close()
            }
        } ?: imageProxy.close()

    }
}

共有1个答案

戚甫
2023-03-14

BarcodeScanning在运行Camera-Camera2:1.0.0-Beta08或更高版本的某些设备上不起作用。您可以使用camera-camera2的早期版本来绕过这个问题。例如:

请参阅:https://developers.google.com/ml-kit/known-issues我们正在为下一个SDK发行版在MLKit中进行内部修复。

 类似资料:
  • 使用ML Kit的条码扫描API,您可以读取大多数使用标准条码格式编码的数据。 条形码是将信息从现实世界传递到应用程序的一种便捷方式。特别是,使用QR码等二维格式时,您可以编码结构化数据,如联系人信息或WiFi网络凭证。由于ML Kit可以自动识别和解析这些数据,因此当用户扫描条形码时,您的应用可以进行智能响应。 iOS Android 关键功能 阅读大多数标准格式 线性格式:Codabar,Co

  • 在基于swift的应用程序中,我必须使用设备摄像机以及使用Linea Pro5(LP5)外部条形码扫描器来实现条形码扫描。在应用程序中,必须检查iPhone与Linea Pro5(LP5)设备的连接状态,如果iPhone未与LP5连接,则必须打开iPhone摄像头,否则将使用LP5进行扫描。我必须对任何UIPutton进行的扫描驻留在应用程序屏幕上。 我的问题是,当我调用connect()方法时,

  • 问题内容: 如何简单地在iPhone和/或iPad上扫描条形码? 问题答案: 我们为iPhone生产了“条形码”应用程序。它可以解码QR码。源代码可从zxing项目获得;具体来说,您想看看iPhone客户端和核心库的部分C ++端口 。该端口从Java代码的0.9发行版开始有点过时了,但仍然可以正常使用。 如果您需要扫描其他格式(例如1D格式),则可以继续将该项目中的Java代码移植到C ++。

  • 我正在使用camerax和google mlkit条形码扫描库来制作一个条形码阅读器。而app扫描qrcode工作良好,但代码格式为条形码,结果会有所不同。条形码有时会扫描多次,例如,有树条形码,但扫描器得到的结果是四个或五个。任何人都知道这个问题,任何帮助都是感激的。图1图2

  • 我正在为平板电脑开发一个android应用程序(SynchroDigital iNOSP10-4.0 RES型号),我想使用ZXing库扫描包含字符串的QRcode。它会在我需要时启动扫描仪,但我无法扫描任何东西。 实际上,如果我直接使用条形码扫描仪应用程序,它甚至不起作用,黄色的点出现了,但什么也没有发生,无论亮度、距离或二维码的复杂性(尝试使用一个只包含字母“a”的巨大二维码),它都不会起作用

  • 您可以使用ML kit来识别并且解码条码。 有关此API使用的示例,请参阅GitHub上的ML Kit快速入门示例。 在开始之前 如果您还没有将Firebase添加到您的程序当中,那您可以从开始指南来开始您的工作。 将ML kit库放进您的Podfile中: pod 'Firebase/Core' pod 'Firebase/MLVision' pod 'Firebase/MLVisionBarc