• Android Camera2获取预览尺寸和fps范围


    升降摄像头安卓手机刚上市的时候,有些很流行的app刚打开时,前置摄像头就升起来了。好像就是出来看一眼然后又收回去。
    虽然我们不调用拍照功能,只是为了获取相机的信息,也是可能让摄像头升起来的。

    Camera实现

    使用android.hardware.Camera获取摄像头支持的预览尺寸和fps。
    Camera.open获取到camera实例,然后再camera.getParameters()

    for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
        Camera camera = null;
        try {
            camera = Camera.open(i);
            Parameters parameters = camera.getParameters();
            supportedSizes = parameters.getSupportedPreviewSizes();
            supportedFpsRanges = parameters.getSupportedPreviewFpsRange();
        } catch (RuntimeException e) {
            Log.e(TAG, "Failed to open, skipping", e);
            continue;
        } finally {
            if (camera != null) {
                camera.release();
            }
        }
    }
    

    android.hardware.Camera:下文简称为「camera」或者「camera1」。

    上面的代码对于可升降摄像头手机(例如荣耀X10)来说,前置摄像头会升起来,然后又缩回去。用户体验不好。

    荣耀X10前置摄像头

    可以用Camera2来实现,不用打开摄像头就能获取到相关信息。

    Camera2

    引入camera2

    首先看模块的gradle。本文示例是放在模块里的。
    我们需要引入androidx相关的包。

    • compileSdk 31
    • androidx.camera:camera-core:1.1.0-beta01
    • androidx.camera:camera-camera2:1.1.0-beta01
    apply plugin: 'com.android.library'
    
    android {
        compileSdk 31
        defaultConfig {
            minSdkVersion 19
            targetSdkVersion 31
            versionCode 110
            versionName "1.1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        implementation fileTree(include: ['*.jar'], dir: 'libs')
        implementation 'androidx.appcompat:appcompat:1.3.1'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    
        implementation "androidx.camera:camera-core:1.1.0-beta01"
        implementation "androidx.camera:camera-camera2:1.1.0-beta01"
    }
    

    注意这里minSdkVersion 19,后面使用的时候需要判断一下运行的Android版本

    这里使用的是beta01版的camera2包,可以看出camera2仍在发展中

    使用

    部分导入的包的情况

    import android.hardware.camera2.CameraAccessException;
    import android.hardware.camera2.CameraCharacteristics;
    import android.hardware.camera2.CameraManager;
    import android.hardware.camera2.params.StreamConfigurationMap;
    import android.os.Build;
    

    用获取系统服务的方式来获取CameraManager,这里要求 API >= 21

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        CameraManager cameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
    }
    

    Camera2相比于camera1的一大不同是,Camera2不需要调用Camera.open方法,就能去查询相机的一些配置。

    获取支持的尺寸。android.hardware包里的Camera.Size已经不推荐使用了(Deprecated)。Camera2用的是android.util.Size

    List<android.util.Size> supportedUtilSize = new ArrayList<>();
    CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("0"); // 0和1
    StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    supportedUtilSize = Arrays.asList(configs.getOutputSizes(ImageFormat.JPEG));
    

    获取支持的fps范围,结果用Range来表示。

    CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("1"); // 0和1
    Range<Integer>[] ranges21 = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
    

    注意上面的代码需要判断系统版本

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        // 在这里面进行操作
    }
    

    Range介绍

    获取fps数据时我们用到了Range类。

    package android.util;
    
    public final class Range<T extends Comparable<? super T>> {
    

    它接受的范型要能够进行比较,即继承Comparable。前面的代码我们用的是Range

    package java.lang;
    
    public final class Integer extends Number implements Comparable<Integer> 
    

    Range表示范围。它代表了一个范围,提供了一些常用的方法。比较类似数学中的集合的概念。

    例如:

    判断目标值是否在范围里public boolean contains(T value)

    判断传入的范围是否在自己的范围里面public boolean contains(Range<T> range)

    获取一个范围内的数值,即限制数值不能超过自己的范围 public T clamp(T value)。假设范围是0到10,传入12,则返回10,也就是上限。

    参考

  • 相关阅读:
    为Ubuntu网页设置稳定的数据隧道
    sqlserver的字符集配置
    嵌入式软件工程师面试题(九)
    git初识
    c++string类的赋值问题
    【华为OD机试真题 JAVA】根据某条件聚类最少交换次数
    富格林:谨防欺诈陷阱安全计策应对
    PHP基于Thinkphp的莆田学院图书馆管理系统毕业设计-附源码071418
    react 组件间的通信
    【数据结构】二叉树的顺序存储结构 —— 堆
  • 原文地址:https://www.cnblogs.com/rustfisher/p/15925841.html