Android(安卓)Camera 预览拉伸
16lz
2021-01-26
现象:
可以看到,相机预览拉伸严重,水杯都被拉伸很细长。
原因:
因为预览的控件(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();
更多相关文章
- Android(安卓)TextView的设置
- Android开发中LogCat工具的使用
- Android(安卓)Stutio设置注释模板
- 怎样动态更换APP图标
- android shape corners 设置无效的解决
- Android(安卓)UI设计总结
- DialogFragment的使用
- Android(安卓)CheckBox使用所遇到的坑
- android浏览器研究-UserAgent