Android CameraX-相机预览在首次调用captureUseCase.takePicture

问题描述

我正在使用android camera X api通过分析检测到的面部来捕获自拍图像。 如果人脸在屏幕上显示的矩形框内,则该应用会捕获5张以上的图像。

问题是,第一次捕获图像时,相机预览会冻结(几秒钟)。

我正在使用以下代码在我的活动中设置摄像头提供商。

//预览用例

internal fun bindPreviewUseCase(previewView: PreviewView) {
    Util.printDebugLog("Binding camera preview use case.")
    if (previewUseCase != null) {
        cameraProvider.unbind(previewUseCase)
    }
    previewUseCase = Preview.Builder()
        .setTargetResolution(Size(480,800))
        .build()
    previewUseCase!!.setSurfaceProvider(previewView.createSurfaceProvider())
    cameraProvider.bindToLifecycle(lifecycleOwner,cameraSelector,previewUseCase)
}

//分析用例

internal fun bindAnalysisUseCase(graphicOverlay: GraphicOverlay) {
        Util.printDebugLog("Binding camera analysis use case.")
        if (analysisUseCase != null) {
            cameraProvider.unbind(analysisUseCase)
        }
        imageProcessor?.stop()
        try {
            val faceDetectorOptions: FaceDetectorOptions = getFaceDetectorOptionsForLivePreview()
            imageProcessor =
                LiveFaceDetectorProcessor(context,faceDetectorOptions,faceFrameProcessListener)
        } catch (e: Exception) {
            Viola.listener.onFaceDetectionFailed(
                FaceDetectionError.IMAGE_PROCESSOR_ERROR,"Can not create image processor: ${e.localizedMessage}"
            )
            return
        }
        val builder = ImageAnalysis.Builder()
        builder.setTargetResolution(Size(480,800))
        analysisUseCase = builder.build()
        needUpdateGraphicOverlayImageSourceInfo = true
        analysisUseCase!!.setAnalyzer(
            ContextCompat.getMainExecutor(context),ImageAnalysis.Analyzer { imageProxy: ImageProxy ->
                if (needUpdateGraphicOverlayImageSourceInfo) {
                    val isImageFlipped =
                        lensFacing == CameraSelector.LENS_FACING_FRONT
                    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
                    if (rotationDegrees == 0 || rotationDegrees == 180) {
                        graphicOverlay.setImageSourceInfo(
                            imageProxy.width,imageProxy.height,isImageFlipped
                        )
                    } else {
                        graphicOverlay.setImageSourceInfo(
                            imageProxy.height,imageProxy.width,isImageFlipped
                        )
                    }
                    needUpdateGraphicOverlayImageSourceInfo = false
                }
                try {
                    imageProcessor!!.processImageProxy(imageProxy,graphicOverlay)
                } catch (e: MlKitException) {
                    Viola.listener.onFaceDetectionFailed(
                        FaceDetectionError.IMAGE_PROCESSOR_ERROR,"Failed to process image: ${e.localizedMessage}"
                    )
                }
            }
        )
        cameraProvider.bindToLifecycle(lifecycleOwner,analysisUseCase)
    }

//捕获用例

internal fun bindCaptureUseCase(previewView: PreviewView) {
    Util.printDebugLog("Binding camera capture use case.")
    if (captureUseCase != null) {
        cameraProvider.unbind(captureUseCase)
    }
    val rotation = previewView.display.rotation
    captureUseCase = ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .setTargetResolution(Size(960,1280))
        .setTargetRotation(rotation)
        .build()
    cameraProvider.bindToLifecycle(lifecycleOwner,captureUseCase)
}

//捕获

internal fun takePicture(callback: CaptureCallback) {
    Util.printDebugLog("Capturing current frame.")
    val diff = System.currentTimeMillis() - lastCaptureTime
    if (diff > captureDelay) {
        if (!isCaptureInProgress) {
            if (captureUseCase == null) {
                return
            }
            isCaptureInProgress = true
            lastCaptureTime = System.currentTimeMillis()
            val executor = ContextCompat.getMainExecutor(context)
            //TODO remove
            val startTime = System.currentTimeMillis()

            captureUseCase!!.takePicture(
                executor,object : ImageCapture.OnImageCapturedCallback() {
                    override fun onCaptureSuccess(image: ImageProxy) {
                        val timeElapsed = System.currentTimeMillis() - startTime
                        Util.printDebugLog("Image captured,producing bitmap from image proxy. $timeElapsed")
                        val bitmap: Bitmap =
                            BitmapUtil.getBitmap(image,image.imageInfo.rotationDegrees)!!
                        image.close()
                        callback.onCaptured(bitmap)
                        isCaptureInProgress = false
                        super.onCaptureSuccess(image)
                    }

                    override fun onError(exception: ImageCaptureException) {
                        super.onError(exception)
                        isCaptureInProgress = false
                        Util.printDebugLog("Unable to capture: ${exception.localizedMessage}")
                    }
                })
        }
    } else {
        Util.printDebugLog("Capture called before minimum delay.Ignoring capture call.")
    }
}

//使用的依赖项

implementation "androidx.camera:camera-camera2:1.0.0-beta07"
implementation "androidx.camera:camera-view:1.0.0-alpha14"
implementation "androidx.camera:camera-lifecycle:1.0.0-beta07"

//每次捕获所花费的时间(以毫秒为单位)

图片1-> 2396
图片2-> 411
图片3-> 356
图片4-> 386
图片5-> 345

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...