Android Camera开发入门(3):CameraX的使用

Android Camera开发入门(3):CameraX的使用

CameraX API简介

在前两篇博客中,我们介绍了Camera基础知识和Camera2 API的使用。为了进一步简化相机应用开发,Google推出了CameraX API,它提供了一个更加简洁、易于使用的接口,帮助开发者快速实现高质量的相机功能。本篇博客将带领你了解CameraX的使用方法,并提供相应的示例代码。

准备工作:

在开始之前,确保你的开发环境已经配置好,Android Studio已更新到最新版本。

依赖添加:

为了使用CameraX API,我们需要在项目的build.gradle文件中添加以下依赖库:

dependencies {
    def camerax_version = "1.0.1"

    // CameraX核心库
    implementation "androidx.camera:camera-core:$camerax_version"
    // CameraX视图库
    implementation "androidx.camera:camera-camera2:$camerax_version"
    // CameraX生命周期库
    implementation "androidx.camera:camera-lifecycle:$camerax_version"
    // CameraX扩展库,用于支持预览和分析
    implementation "androidx.camera:camera-view:1.0.0-alpha28"
}

初始化CameraX:

首先,我们需要在Activity或Fragment中初始化CameraX。以下是一个示例:

private lateinit var cameraProvider: ProcessCameraProvider
    private lateinit var preview: Preview

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            cameraProvider = cameraProviderFuture.get()

            bindCameraUseCases()
        }, ContextCompat.getMainExecutor(this))
    }

    @SuppressLint("RestrictedApi")
    private fun bindCameraUseCases() {
        val cameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
            .build()

        //previewView预览
        preview = Preview.Builder().build()
        //拍照
        imageCapture = ImageCapture.Builder()
            .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
            .build()
        //录像
        videoCapture = VideoCapture.Builder()//录像用例配置
            .setTargetAspectRatio(AspectRatio.RATIO_16_9) //设置高宽比
            .setTargetRotation(ROTATION_90)//设置旋转角度
            .setAudioRecordSource(MediaRecorder.AudioSource.MIC)//设置音频源麦克风
            .build()

        //解绑用例
        cameraProvider.unbindAll()
        //绑定用例
        cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture, videoCapture)

        //开始预览 previewView
        preview.setSurfaceProvider(binding!!.previewView.surfaceProvider)
    }

在上述代码中,我们通过调用ProcessCameraProvider.getInstance()来获取CameraX的实例。然后,我们使用bindToLifecycle()方法绑定相机的生命周期,并指定预览用例。

设置预览:

为了在界面上显示相机预览,我们需要在布局文件中添加一个PreviewView元素。以下是一个示例布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CameraXActivity">

    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/camerax_takePicture"
        android:text="开始拍照"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

    <Button
        android:id="@+id/camerax_recording"
        android:text="开启录制"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/camerax_takePicture"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在Activity或Fragment中,我们将使用PreviewView显示相机预览。在上面的示例代码中,我们通过previewView.createSurfaceProvider()方法将预览与相机绑定起来。

通过上述步骤,我们已经成功实现了使用CameraX显示相机预览的功能。你可以尝试运行应用程序,在设备上查看相机预览的效果。

拍照

CameraX不论拍照还是录制都比Camera和Camera2简单,只要绑定了相关用例,后续直接调用即可;

 	binding!!.cameraxTakePicture.setOnClickListener {
            takePicture()
    }
	 //拍照
    private var imageCapture: ImageCapture? = null
    private fun takePicture() {
        val outputFile = File(this.getExternalFilesDir(null), "${System.currentTimeMillis()}.jpg")
        Log.e(TAG, "照片文件: ${outputFile.absolutePath}")
        val outputOptions = ImageCapture.OutputFileOptions.Builder(outputFile).build()
        imageCapture?.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                    // 图片保存成功后的处理逻辑
                    Toast.makeText(this@CameraXActivity, "拍照成功", Toast.LENGTH_SHORT).show()
                }

                override fun onError(exception: ImageCaptureException) {
                    // 拍照失败的处理逻辑
                    Toast.makeText(this@CameraXActivity, "拍照失败", Toast.LENGTH_SHORT).show()
                }
            })
    }

录像

和拍照类似,CameraX更像是一个封装好的第三方依赖,只要了解具体用法,相对于前两者,使用起来都更加简单明了;

	binding!!.cameraxRecording.setOnClickListener {
            if (!isRecording) startRecording() else stopRecording()
    }
	//录像
    private var isRecording = false
    private var videoCapture: VideoCapture? = null
    private fun startRecording() {
        val outputFile = File(this.getExternalFilesDir(null), "${System.currentTimeMillis()}.mp4")
        Log.e(TAG, "视频文件: ${outputFile.absolutePath}")
        val outputOptions = VideoCapture.OutputFileOptions.Builder(outputFile).build()
        videoCapture?.startRecording(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : VideoCapture.OnVideoSavedCallback {
                override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
                    // 录制保存成功后的处理逻辑
                    Toast.makeText(this@CameraXActivity, "录制保存成功", Toast.LENGTH_SHORT).show()
                    isRecording = false
                }

                override fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
                    // 录制保存失败的处理逻辑
                    Toast.makeText(this@CameraXActivity, "录制保存失败", Toast.LENGTH_SHORT).show()
                    isRecording = false
                }
            })
        isRecording = true
    }

    private fun stopRecording() {
        videoCapture?.stopRecording()
        isRecording = false
    }

结论:

通过本篇博客,我们了解了CameraX API的基本使用方法,并实现了显示相机预览的功能。CameraX提供了更加简单、易于使用的接口,简化了相机应用的开发流程,使我们能够更加专注于核心功能的实现。在下一篇博客中,我们将深入介绍CameraX API的更多功能,如拍照、录制视频、图像分析等。

参考链接

CameraX官方文档
CameraX官方文档提供了CameraX API的详细说明,包括核心概念、基本用法、高级特性等内容。

CameraX示例代码
Google官方提供的CameraX示例代码,展示了CameraX API的使用方法和最佳实践,你可以从中学习和参考。

CameraX开发者指南
Google官方提供的Codelab,逐步引导你了解和使用CameraX API,通过实践来掌握CameraX的常用功能。

CameraX扩展库
CameraX扩展库提供了一组专门针对预览、图像分析和视频录制的功能扩展,帮助你更便捷地实现常见相机功能。

DEMO


该系列文章到这里也就算结束了,后续我将考虑推出更多关于不同版本之间如何添加水印、滤镜以及视频编码等相关功能的简介文章。期待与您分享更多有关相机功能的内容!如果您还有其他问题或需求,请随时告诉我们。谢谢!

gitee:https://gitee.com/yunianvh/camera-demo
github:https://github.com/yunianvh/CameraDemo

编辑:玉念聿辉
感谢查阅

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉念聿辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值