Android 6.0獲取攝像頭支持分辨率列表并格式化輸出

Android開(kāi)發(fā)中經(jīng)常需要獲取攝像頭所支持的分辨率列表,然而獲取的參數(shù)列表是List形式,而且每個(gè)分辨率并不是按大小進(jìn)行排列,不方便查看和返回,所以寫(xiě)了一個(gè)重新排列并且格式化輸出的方法。

Camera.Parameters有三個(gè)方法獲取分辨率:

獲取攝像頭支持的視頻分辨率列表
getSupportedVideoSizes();

獲取攝像頭支持的圖像分辨率列表
getSupportedPictureSizes();

獲取攝像頭預(yù)覽分辨率(一般是預(yù)設(shè)的推薦分辨率)
getSupportedPreviewSizes();

理論上需要獲取預(yù)覽分辨率和支持分辨率兩個(gè)值,用來(lái)保證設(shè)置攝像頭的分辨率后不會(huì)出現(xiàn)一些玄學(xué)概率問(wèn)題(通常是攝像頭推薦的分辨率和最高分辨率的沖突),在實(shí)際開(kāi)發(fā)中我用getSupportedVideoSizes()和getSupportedPreviewSizes()死活獲取不到值,只能通過(guò)getSupportedPictureSizes()拉取列表,獲取到的分辨率也是一致的。

需要注意的是,CPU型號(hào)也會(huì)影響分辨率的獲取,同一個(gè)攝像頭在不同CPU上拉取到的支持分辨率是不一樣的,所以還需要對(duì)不同CPU機(jī)型的攝像頭分辨率進(jìn)行適配。

數(shù)據(jù)定義

    public static List<Camera.Size> supportedVideoSizes;
    public static List<Camera.Size> previewSizes;

獲取攝像頭信息,然后循環(huán)取最大的width和height,(最大值一般是List的第一個(gè)元素,可以直接get(0)),但是有些攝像頭拉去到的list是亂序的,所以對(duì)他們進(jìn)行重新按大小排序,方便取值。width*height就是攝像頭的像素,例如500百萬(wàn)像素。

    public String getCameraInfo(){

        int cameracount = 0;//攝像頭數(shù)量
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();  //獲取攝像頭信息
        cameracount = Camera.getNumberOfCameras();
        Log.i("CameraTest","攝像頭數(shù)量"+String.valueOf(cameracount));
        for(int cameraId=0; cameraId<Camera.getNumberOfCameras(); cameraId++)
        {
            Camera.getCameraInfo( cameraId, cameraInfo);  
            Camera camera = Camera.open(cameraId); //開(kāi)啟攝像頭獲得一個(gè)Camera的實(shí)例
            Camera.Parameters params = camera.getParameters();  //通過(guò)getParameters獲取參數(shù)
            supportedVideoSizes = params.getSupportedPictureSizes();
            previewSizes = params.getSupportedPreviewSizes();
            camera.release();//釋放攝像頭

            //重新排列后設(shè)下攝像頭預(yù)設(shè)分辨率在所有分辨率列表中的地址,用以選擇最佳分辨率(保證適配不出錯(cuò))
            int index=bestVideoSize(previewSizes.get(0).width);
            Log.i("CameraTest", "預(yù)覽分辨率地址: " + index );
            if (null != previewSizes && previewSizes.size() > 0){  //判斷是否獲取到值,否則會(huì)報(bào)空對(duì)象
                Log.i("CameraTest", "攝像頭最高分辨率寬: " + String.valueOf(supportedVideoSizes.get(0).width) );  //降序后取最高值,返回的是int類(lèi)型
                Log.i("CameraTest", "攝像頭最高分辨率高: " + String.valueOf(supportedVideoSizes.get(0).height) );
                Log.i("CameraTest", "攝像頭分辨率全部: " + cameraSizeToSting( supportedVideoSizes) );  
            }else{
                Log.i("CameraTest", "沒(méi)取到值啊什么鬼" );
                Log.i("CameraTest", "攝像頭預(yù)覽分辨率: " + String.valueOf(previewSizes.get(0).width) ); 
            }
        }
        return cameraSizeToSting( supportedVideoSizes );
    }

重新排列分辨率列表

    //重新排列獲取到的分辨率列表
    public static int bestVideoSize(int _wid) {

        //降序排列
        Collections.sort(supportedVideoSizes, new Comparator<Camera.Size>() {
            @Override
            public int compare(Camera.Size lhs, Camera.Size rhs) {
                if (lhs.width > rhs.width) {
                    return -1;
                } else if (lhs.width == rhs.width) {
                    return 0;
                } else {
                    return 1;
                }
            }
        });
        for (int i = 0; i < supportedVideoSizes.size(); i++) {
            if (supportedVideoSizes.get(i).width < _wid) {
                return i;
            }
        }
        return 0;
    }

格式化輸出成常見(jiàn)的寬x高格式

    //分辨率格式化輸出String值
    public static String cameraSizeToSting(Iterable<Camera.Size> sizes)
    {
        StringBuilder s = new StringBuilder();
        for (Camera.Size size : sizes)
        {
            if (s.length() != 0)
                s.append(",\n");
            s.append(size.width).append('x').append(size.height);
        }
        return s.toString();
    }

使用完相機(jī)之后一定要記得用 Camera.release()來(lái)釋放相機(jī)的實(shí)例,否則后續(xù)調(diào)用相機(jī)的請(qǐng)求(系統(tǒng)內(nèi)其他app或本應(yīng)用)都會(huì)失敗,導(dǎo)致Camera.open()方法報(bào)錯(cuò)“Failed to connect to camera service”。所以同理,出現(xiàn)這種問(wèn)題的時(shí)候也可以排查系統(tǒng)中其他apps是否正在占用攝像頭沒(méi)有釋放。

在Android 6.0版本的攝像頭開(kāi)發(fā)中,使用Camera.open()方法時(shí),需要在onCreate()方法中加入下面的權(quán)限申請(qǐng),否則同樣會(huì)報(bào)錯(cuò)"Failed to connect to camera service"

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //android6.0需要加申請(qǐng)權(quán)限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
            }
        }
    }

運(yùn)行結(jié)果如下


屏幕快照 2018-04-13 11.49.32.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容