现象:


可以看到,相机预览拉伸严重,水杯都被拉伸很细长。

原因:

因为预览的控件(SurfaceView) 和相机输出的图像,宽高比不一致导致。我们需要统一控件的宽高比和相机输出的宽高比。

解决方法:

自定义一个SurfaceView,根据给定的宽高比,进行设置自身的宽高。

public class AutoFitSurfaceView extends SurfaceView {    private float mAspectRatio;    public AutoFitSurfaceView(Context context) {        super(context);    }    public AutoFitSurfaceView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public AutoFitSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public void setAspectRatio(int width,int height){        mAspectRatio = (float)width / height;        getHolder().setFixedSize(width,height);        requestLayout();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = MeasureSpec.getSize(widthMeasureSpec);        int height = MeasureSpec.getSize(heightMeasureSpec);        if (mAspectRatio == 0) {            setMeasuredDimension(width,height);        }else {            int newW,newH;            float actualRatio;            if (width > height) {                actualRatio = mAspectRatio;            }else {                actualRatio = 1/ mAspectRatio;            }            if (width < height * actualRatio){                newH = height;                newW = (int) (height * actualRatio);            }else {                newW = width;                newH = (int) (width /actualRatio);            }            setMeasuredDimension(newW,newH);        }    }}

增加SurfaceView 创建的监听,拿到相机支持输出的宽高,计算合适的宽高,设置给自定义的SurfaceView.

        mSurfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {            @Override            public void surfaceCreated(SurfaceHolder holder) {                Log.d("CameraFragment", "surfaceCreated");                mSupportSize = CameraUtils.getSupportSize(mRoot, 0, 0, mCamera.getParameters().getSupportedPreviewSizes());                mSurfaceView.setAspectRatio(mSupportSize.width, mSupportSize.height);                    mRoot.post(new Runnable() {                        @Override                        public void run() {                            initCamera(mSurfaceView);                        }                    });            }            @Override            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            }            @Override            public void surfaceDestroyed(SurfaceHolder holder) {                Log.d("CameraFragment", "surfaceDestroyed");            }        });    public static Camera.Size getSupportSize(View view, int width, int height, List allSize){        Display display = view.getDisplay();        Point point = new Point();        display.getSize(point);        for (Camera.Size size : allSize) {            if (size.width <= point.y && size.height <= point.x) {                return size;            }        }        return allSize.get(0);    }

初始化相机的时候,指定相机预览的宽高为上一步设置的宽高。

    private void initCamera(AutoFitSurfaceView surfaceView) {        try {            mCamera.setPreviewDisplay(surfaceView.getHolder());            mCamera.setAutoFocusMoveCallback(new Camera.AutoFocusMoveCallback() {                @Override                public void onAutoFocusMoving(boolean start, Camera camera) {                    Log.d("CameraFragment", "onAutoFocusMoving start:" + start);                }            });            mCamera.setDisplayOrientation(90);            Camera.Parameters parameters = mCamera.getParameters();            // 拿到支持的输出分辨率    这个分辨率好像是横屏*竖屏 比如 1920*1080            List supportedPreviewSizes = parameters.getSupportedPreviewSizes();            //设置输出的分辨率            parameters.setPreviewSize(mSupportSize.width, mSupportSize.height);            //持续对焦模式  这种模式下不能调用autoFocus            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);            parameters.setJpegQuality(100);            //设置拍照的格式            parameters.setPictureFormat(ImageFormat.JPEG);            //设置拍照的分辨率            parameters.setPictureSize(mSupportSize.width, mSupportSize.height);            mCamera.setParameters(parameters);            mCamera.startPreview();

更多相关文章

  1. Android(安卓)TextView的设置
  2. Android开发中LogCat工具的使用
  3. Android(安卓)Stutio设置注释模板
  4. 怎样动态更换APP图标
  5. android shape corners 设置无效的解决
  6. Android(安卓)UI设计总结
  7. DialogFragment的使用
  8. Android(安卓)CheckBox使用所遇到的坑
  9. android浏览器研究-UserAgent

随机推荐

  1. Android分分钟教你写一个个性化的加载框
  2. Gradle: Download: http://repo1.maven..
  3. 浅析Android录屏 MediaRecorder
  4. Api级别详解
  5. Android(安卓)静默安装程序(在后台偷偷安
  6. Android(安卓)dialog——点击「屏幕」或
  7. Android(安卓)创世纪 第三天
  8. android ProgressBar定制模式,自定义模式
  9. android anr traces日志分析方法
  10. Android解锁屏幕失效问题