Android 基于Camera2 API进行摄像机图像预览

前言

近期博主准备编写一个基于Android Camera2的图像采集并编码为h.264的应用,准备分为三个阶段来完成,第一阶段实现Camera2的摄像机预览,第二阶段完成基于MediaCodec H.264编码,第三阶段完成基于MediaCodec H.264解码,针对不同阶段将输出对应的实现博文,因为笔者是第一次接触这块因此如果编写过程中有什么错误的话,欢迎大家指正,对于技术方面感兴趣的也欢迎私信或者留言,一起讨论共同进步。

Camera2 API简介

Android Camera2 API 是从 Android 5.0(Lollipop)开始引入的,用以取代旧的 Camera API。Camera2 提供了更强大和灵活的相机控制能力,允许开发者实现更多的相机功能,如手动对焦、手动曝光、原生 RAW 图像捕获等。

在开始使用Camera2之前,我们先来了解下Camera2使用过程中需要用到的相关类:

  • CameraManager:相机管理器,安卓系统针对不同的功能模块会创建不同的Manager,所以相机也不例外,一般主要用来open相机或者查询相机列表以及对应相机的参数等。

  • CameraDevice:代表一个物理相机设备,可以打开、配置和关闭相机设备等。

  • CameraCaptureSession:相机捕获会话,用于发送捕获请求和接收捕获结果,可以预览、拍照、录像等。

  • CameraCharacteristics:提供了相机设备的静态信息,如支持的参数、分辨率、对焦模式等。

整个执行流程大致上如下:

flowchart TB
    获取CameraManager对象 --> 通过CameraManager打开指定ID的相机 --> 打开后拿到到CameraDevice对象 --> 通过CameraDevice创建CameraCaptureSession对象 --> 通过CameraCaptureSession开启预览

现在已经简单的知晓了相关类的用途和流程,那么我们接下来开始实现Camera2的预览功能。

编码实现

为了方便后续对这块的复用,因此这里我们创建一个名为CameraWrapper的类,用以对Camera相关功能的封装,首先添加如下代码:

class CameraWrapper(private var context:Context) {
   
   

    private val TAG = "CameraWrapper"

    private var cameraManager: CameraManager
    private var cameraDevice: CameraDevice? = null
    private var characteristics: CameraCharacteristics? = null
    private var session: CameraCaptureSession? = null

    //当前设备的相机列表
    private var cameraIds:Array<String>

    //默认启用的cameraId
    private var cameraId:String = "0"//默认前置

    private var previewView:SurfaceView? = null

    private  var encoderSurface: Surface? = null

    private var cameraThread:HandlerThread = HandlerThread("CameraThread")
    private var cameraHandler: Handler

    private var previewSize:Size? = Size(1280,720)
    
    init {
   
   
        cameraThread.start()
        cameraHandler = Handler(cameraThread.looper)
        cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
        cameraIds = getCameraIds()

        //看下id和前后置的对应关系
        for(id in cameraIds){
   
   
            Log.d(TAG,"id : "+id+"---"+getCameraOrientationString(id))
        }

         useCamera(cameraId)
    }

这里我们定义了所有需要用到的成员变量,这里我挑几个说明下,其他的就不过多说明了,看名字应该都能理解。

通过previewView应该不难看出我们使用的预览View为SurfaceView。

encoderSurface这个预留给后续摄像机编码H.264时使用,本篇文章暂未用到。

cameraThread和cameraHandler这里可以不用过多关注,创建的意义主要是传参给Camera,使用是在Camera内。

previewSize可以理解为预览的画面分辨率,默认设置的是720P。

该类类创建时,获取到了设备支持的摄像机列表并打印了前后置的对应关系,这里主要是调试观察的。getCameraIds()和 useCamera(cameraId)我们还没实现,但是先不急,让我们先加两个权限相关的函数。

   //添加权限请求和检查接口,方便使用
    companion object{
   
   
         fun requestCameraPermissions(activity: Activity){
   
   
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(
                    Manifest.permission.CAMERA,
                ),
                998
            )
        }

        fun checkCameraPermission(context: Context):Boolean{
   
   
            return ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
        }
    }

这两个函数作用就不解释了,核心作用就是为了方便使用CameraWrapper时对相关权限进行检查和请求。

 fun useCamera(id:String){
   
   
        cameraId = id
        try {
   
   
            characteristics = cameraManager.getCameraCharacteristics(cameraId
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值