Camera2的一些关键API的补充

780 阅读6分钟

之前写一个Camera2 的时候,后面的编码发现要指定支持的分辨率编码后才能正常的播放,在这里做一点补充。

一些常用的类和API

CameraCharacteristics

Android Camera2的CameraCharacteristics是描述摄像头设备属性和功能的一组键值对。每个摄像头都有相应的Characteristics对象,可以通过CameraManager.getCameraCharacteristics()方法获取。

Android Camera2的characteristics通常包括以下功能:

  1. 支持的图像输出格式:描述摄像头支持的图像格式,如JPEG、RAW等。

  2. 分辨率支持:描述摄像头支持的不同分辨率选项,用于拍摄照片或录制视频。

  3. 对焦模式:描述摄像头支持的不同对焦模式,如自动对焦、连续对焦、手动对焦等。

  4. 曝光模式:描述摄像头支持的曝光模式,如自动曝光、连续曝光、手动曝光等。

  5. 快门速度范围:描述摄像头支持的快门速度范围,用于控制曝光时间。

  6. 传感器角度:描述摄像头传感器的方向和角度。

  7. 支持的稳定性:描述摄像头是否支持图像稳定功能。

  8. 支持的闪光灯模式:描述摄像头支持的不同闪光灯模式,如自动闪光、关闭闪光、打开闪光等。

  9. 支持的人脸检测功能:描述摄像头是否支持人脸检测功能。

  10. 支持的相机控制功能:描述摄像头是否支持手动调节焦距、ISO、白平衡等参数的功能。

这些characteristics可以帮助开发者了解和配置摄像头设备,以便根据需求选择合适的设置和功能。

里面定义了很多常量,我们可以通过常量去拿到Camera的各种属性和特性,这些常量有:

  1. SENSOR_ORIENTATION:表示相机传感器相对于设备自然方向的方向,以度数表示。该值可以用于校准图像的方向。

  2. LENS_FACING:表示相机镜头的朝向,包括前置摄像头、后置摄像头或外部摄像头。

  3. COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES:表示相机支持的颜色校正畸变模式列表,包括 OFF、FAST 和 HIGH_QUALITY 三种模式。

  4. CONTROL_AF_AVAILABLE_MODES:表示相机支持的对焦模式列表,包括自动对焦、连续对焦、手动对焦等。

  5. CONTROL_AE_AVAILABLE_MODES:表示相机支持的曝光模式列表,包括自动曝光、连续曝光、手动曝光等。

  6. FLASH_INFO_AVAILABLE:表示相机是否支持闪光灯功能。

  7. SCALER_AVAILABLE_MAX_DIGITAL_ZOOM:表示相机支持的最大数字缩放级别。

  8. SCALER_STREAM_CONFIGURATION_MAP:表示相机所有支持的输出格式和分辨率的 Map 对象。该对象可以用于获取设备支持的拍照分辨率和录像分辨率等信息。

  9. SENSOR_INFO_PIXEL_ARRAY_SIZE:表示相机传感器的像素数组大小,以像素为单位。

  10. SENSOR_INFO_EXPOSURE_TIME_RANGE:表示相机支持的快门速度范围,以纳秒为单位。

  11. LENS_INFO_AVAILABLE_FOCAL_LENGTHS:表示相机支持的焦距列表,以毫米为单位。

  12. REQUEST_AVAILABLE_CAPABILITIES:表示相机支持的请求功能列表,包括基本模式、高速率模式、人脸检测等。

下面是一个获取Camera支持的分辨率:

private data class CameraInfo(
    val name: String,
    val cameraId: String,
    val size: Size,
    val fps: Int)

/** Converts a lens orientation enum into a human-readable string */
private fun lensOrientationString(value: Int) = when (value) {
    CameraCharacteristics.LENS_FACING_BACK -> "Back"
    CameraCharacteristics.LENS_FACING_FRONT -> "Front"
    CameraCharacteristics.LENS_FACING_EXTERNAL -> "External"
    else -> "Unknown"
}

/**
 * 列出所有具有视频功能的相机以及支持的分辨率和FPS组合
 * 格式:Front(1) 1280*720 30 FPS
 */
@SuppressLint("InlinedApi")
private fun enumerateVideoCameras(cameraManager: CameraManager): List<CameraInfo> {
    val availableCameras: MutableList<CameraInfo> = mutableListOf()

    cameraManager.cameraIdList.forEach { id ->
        val characteristics = cameraManager.getCameraCharacteristics(id)
        // 摄像头类型,前摄像头还是后摄像头
        val orientation = lensOrientationString(
            characteristics.get(CameraCharacteristics.LENS_FACING)!!)

        // 查询可用的功能和输出格式
        val capabilities = characteristics.get(
            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)!!
        // 获取相机支持的所有输出配置,包括分辨率、输出格式等。通过此 API,可以获取相机支持的拍照分辨率和录制视频的分辨率等信息。
        val cameraConfig = characteristics.get(
            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!

        // 获取相机向后兼容的特性,相机设备具有向后兼容性,即它可以与旧版的 Camera2 API 兼容,并支持较旧版本的功能和操作方式。
        if (capabilities.contains(
                CameraCharacteristics
                .REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE)) {

            val targetClass = MediaRecorder::class.java

            // getOutputSizes:方法用于获取相机设备支持的输出尺寸列表。该方法返回一个Size[]数组,表示相机设备支持的各种输出尺寸选项。
            cameraConfig.getOutputSizes(targetClass).forEach { size ->
                // 每一秒帧耗费的时间
                val secondsPerFrame =
                    cameraConfig.getOutputMinFrameDuration(targetClass, size) /
                            1_000_000_000.0
                // 计算出帧率
                val fps = if (secondsPerFrame > 0) (1.0 / secondsPerFrame).toInt() else 0
                val fpsLabel = if (fps > 0) "$fps" else "N/A"
                availableCameras.add(CameraInfo(
                    "$orientation ($id) $size $fpsLabel FPS", id, size, fps))
            }
        }
    }

    return availableCameras
}

获取分辨率的API是: Camera2中的cameraConfig.getOutputSizes方法用于获取相机设备支持的输出尺寸列表。该方法返回一个Size[]数组,表示相机设备支持的各种输出尺寸选项。

getOutputSizes方法可以用于确定相机可以产生的不同图像和视频输出的分辨率大小。通过遍历返回的Size数组,可以获取所有可用的输出尺寸选项,并根据需要选择最适合的分辨率配置。

传入的参数是一个Class类型的参数,用于指定所需的输出类别。通常情况下,常见的输出类别包括:

  • ImageReader.class:静态图像的输出。
  • MediaRecorder.class:录制视频的输出。
  • SurfaceHolder.class:将相机数据直接渲染到SurfaceView的输出。
  • MediaCodec.class:编码的输出
  • SurfaceTexture.class:纹理的输出
  • Allocation.class:相机设备支持的可用内存分配尺寸列表。 例如,如果要获取相机设备支持的预览尺寸列表,可以传入SurfaceHolder.class作为参数,然后使用返回的Size[]数组来选择最合适的预览尺寸配置。而如果希望获取相机设备支持的照片尺寸列表,可以传入ImageReader.class作为参数。

一些额为的小知识

480P、720P、1080P 这些分辨率是什么意思

可能有些小伙伴也会和我一样开始的时候弄不清楚这些是什么,其实这些数值就是对应的高度。

  • 480P(流畅):高是480,如果视频的比例是 16:9,那对应的宽度就是 480 * 16/9 = 853 (一般取整数);如果视频的比例是 4:3,那对应的宽度就是 480 * 4/3 = 640
  • 720P(标清):高是480,如果视频的比例是 16:9,那对应的宽度就是 720 * 16/9 = 1280 ;如果视频的比例是 4:3,那对应的宽度就是 720 * 4/3 = 960
  • 1080P(高清):高是480,如果视频的比例是 16:9,那对应的宽度就是 1080 * 16/9 = 1920 ;如果视频的比例是 4:3,那对应的宽度就是 1080 * 4/3 = 1440

今天就补充了如何获取分辨率信息。