返回

使用Camerax简化Android中的拍照、录像和二维码扫描

Android

使用 Camerax 实现照片、视频和二维码扫描:逐步指南

拍照

使用 Camerax 拍照非常简单。只需创建一个 ImageCapture 用例,并设置一个点击侦听器来响应用户点击拍照按钮:

val imageCaptureUseCase = ImageCapture.Builder().build()
captureButton.setOnClickListener {
    imageCaptureUseCase.takePicture(executor, object : ImageCapture.OnImageCapturedCallback() {
        override fun onCaptureSuccess(image: ImageProxy) {
            // 保存图像
        }

        override fun onError(exception: ImageCaptureException) {
            // 处理错误
        }
    })
}

录像

使用 Camerax 录制视频的过程与拍照类似。创建一个 VideoCapture 用例,并设置一个点击侦听器来响应用户点击录制视频按钮:

val videoCaptureUseCase = VideoCapture.Builder().build()
recordButton.setOnClickListener {
    videoCaptureUseCase.startRecording(executor, outputFileOptions, object : VideoCapture.OnVideoSavedCallback {
        override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
            // 保存视频文件
        }

        override fun onError(videoCaptureError: VideoCapture.VideoCaptureError) {
            // 处理错误
        }
    })
}

二维码扫描

使用 Camerax 进行二维码扫描需要借助 ML Kit 中的 BarcodeScanning API。首先,获取一个 BarcodeScanner 客户端,然后创建一个 ImageAnalysis 用例来处理相机预览帧:

val barcodeScanner = BarcodeScanner.getClient()
val imageAnalysisUseCase = ImageAnalysis.Builder().build().also {
    it.setAnalyzer(executor, object : ImageAnalysis.Analyzer {
        override fun analyze(image: ImageProxy) {
            barcodeScanner.process(image) { barcodes ->
                // 处理二维码结果
            }
        }
    })
}

代码示例

以下是一个使用 Camerax 实现照片、视频和二维码扫描的完整代码示例:

class CameraActivity : AppCompatActivity() {

    private lateinit var cameraProvider: CameraProvider
    private lateinit var previewView: PreviewView
    private lateinit var imageCaptureUseCase: ImageCapture
    private lateinit var videoCaptureUseCase: VideoCapture
    private lateinit var barcodeScanner: BarcodeScanner
    private lateinit var imageAnalysisUseCase: ImageAnalysis

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_camera)

        cameraProvider = CameraProvider.getInstance()
        previewView = findViewById(R.id.previewView)

        imageCaptureUseCase = ImageCapture.Builder().build()
        videoCaptureUseCase = VideoCapture.Builder().build()
        barcodeScanner = BarcodeScanner.getClient()
        imageAnalysisUseCase = ImageAnalysis.Builder().build().also {
            it.setAnalyzer(executor, object : ImageAnalysis.Analyzer {
                override fun analyze(image: ImageProxy) {
                    barcodeScanner.process(image) { barcodes ->
                        // 处理二维码结果
                    }
                }
            })
        }

        cameraProvider.bindToLifecycle(lifecycle, CameraSelector.DEFAULT_BACK_CAMERA, previewView, imageCaptureUseCase, videoCaptureUseCase, imageAnalysisUseCase)

        captureButton.setOnClickListener {
            imageCaptureUseCase.takePicture(executor, object : ImageCapture.OnImageCapturedCallback() {
                override fun onCaptureSuccess(image: ImageProxy) {
                    // 保存图像
                }

                override fun onError(exception: ImageCaptureException) {
                    // 处理错误
                }
            })
        }

        recordButton.setOnClickListener {
            videoCaptureUseCase.startRecording(executor, outputFileOptions, object : VideoCapture.OnVideoSavedCallback {
                override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
                    // 保存视频文件
                }

                override fun onError(videoCaptureError: VideoCapture.VideoCaptureError) {
                    // 处理错误
                }
            })
        }
    }
}

常见问题解答

  1. 如何使用前置摄像头拍照?

    • 使用 CameraSelector.DEFAULT_FRONT_CAMERA 代替 CameraSelector.DEFAULT_BACK_CAMERA 来选择前置摄像头。
  2. 如何更改预览分辨率?

    • 在 Preview.Builder 中设置 desiredResolution 来更改预览分辨率。
  3. 如何禁用自动对焦?

    • 在 ImageCapture.Builder 中设置 len