Camera开发中使用surfaceview预览自适应比例

转载注明出处 http://blog.csdn.net/sung_ll/article/details/72929698

前言

app需要增加类似美拍的段视频拍摄功能,在实际的开发中碰到surface view预览的变形。参考了网上的资料,提出了解决办法


思路

在camera的开发中,因为不同手机硬件的原因,所支持的分辨率都不一样,所以在surface view预览的时候需要同时考虑到surface view的大小比例以及camera的画面比例,然而在设置比例尺的时候如若传入不支持的宽高,camera的画面是传递不过来的,所以只能根据手机支持的比例来改变surface大小及画面。注,surfaceveiw比例、camera画面比例、pictrue size比例三者必须一致。


正文

本文只讲问题的处理,camera开发不作赘述

首先是找到关键的设置,有两个地方

1是surface view初始化时大小的设置

mSurfaceView.setLayoutParams(lp);

2是视频比例的设置

mParameters.setPreviewSize(previewSize.width,previewSize.height);


接下来分析

因为分辨率必须是手机硬件支持的尺寸才能显示出画面,所以预览的设置只有以下两种情况:

1固定比例,surface大小根据 屏幕宽 和 比例尺 动态设置高度,camera分辨率传入固定值

市场安卓机器一般支持的尺寸高度有:240,480,720,1080等。屏幕比例大多4:3或者16:9,使用时根据需要自定,具体值可用以下api获取

mParameters.getSupportedPreviewFrameRates();

使用固定比例时,机器的不同屏幕比例也不同,当固定比例不同等于屏幕时就会出现预览图像上下白边的情况,所以这时候就需要使用第二种

2动态选择比例

初始化时获取屏幕的比例

/** 获取屏幕比例*/
    public static float getScreenScale(Context context){
        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        return (float) (display.getHeight()) / (float) (display.getWidth());
    }
获取屏幕比例height和width计算时需要时float或者double类型,结果带小数


传入获取到的支持的分辨率列表list,最小宽度,屏幕比例。返回合适的camera分辨率

public Camera.Size getPreviewSize(List<Camera.Size> list, int th, float scale){
        Collections.sort(list, sizeComparator);

        //Log.e(tag,"prepareCameraParaments:scale-"+scale);
        int i = 0;
        for(Camera.Size s:list){
            if((s.width > th) && equalRate(s, scale)){
                Log.i(tag, "最终设置预览尺寸:w = " + s.width + "h = " + s.height);
                break;
            }
            i++;
        }

        return list.get(i);
    }

最后在同时修改surfaceview满屏和设置camera分辨率


延伸

贴上尺寸获取的工具类

/**
 * Created by sung on 2017/6/8.
 */

public class CameraSizeUtils {
    private static final String tag = "yan";
    private CameraSizeComparator sizeComparator = new CameraSizeComparator();
    private static CameraSizeUtils myCamPara = null;
    public static float SCREEN_SCALE = 4/3;

    private CameraSizeUtils(){

    }
    public static CameraSizeUtils getInstance(){
        if(myCamPara == null){
            myCamPara = new CameraSizeUtils();
            return myCamPara;
        }
        else{
            return myCamPara;
        }
    }

    public Camera.Size getPreviewSize(List<Camera.Size> list, int th, float scale){
        Collections.sort(list, sizeComparator);

        //Log.e(tag,"prepareCameraParaments:scale-"+scale);
        int i = 0;
        for(Camera.Size s:list){
            if((s.width > th) && equalRate(s, scale)){
                Log.i(tag, "最终设置预览尺寸:w = " + s.width + "h = " + s.height);
                break;
            }
            i++;
        }

        return list.get(i);
    }

    public Camera.Size getPictureSize(List<Camera.Size> list, int th, float scale){
        Collections.sort(list, sizeComparator);

        int i = 0;
        for(Camera.Size s:list){
            if((s.width > th) && equalRate(s, scale)){
                Log.i(tag, "最终设置图片尺寸:w = " + s.width + "h = " + s.height);
                break;
            }
            i++;
        }

        return list.get(i);
    }

    public boolean equalRate(Camera.Size s, float rate){
        float r = (float)(s.width)/(float)(s.height);
        if(Math.abs(r - rate) <= 0.2)
        {
            return true;
        }
        else{
            return false;
        }
    }

    public  class CameraSizeComparator implements Comparator<Camera.Size> {
        //按升序排列  
        public int compare(Camera.Size lhs, Camera.Size rhs) {
            // TODO Auto-generated method stub  
            if(lhs.width == rhs.width){
                return 0;
            }
            else if(lhs.width > rhs.width){
                return 1;
            }
            else{
                return -1;
            }
        }

    }
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值