也是重构第二版,讲述了两种实现全屏的解决方案,第一种是我想到的,第二种是参考网上大佬的解决方案。各有优缺点。
相机预览画面被拉伸变形?
我们要知道
- 首先设备的屏幕分辨率是固定不会变化的。
- 设备的相机硬件会提供若干组可以拍摄照片的大小。
也就是说,相机硬件所提供的照片尺寸未必完全(99%不会)和屏幕分辨率保持一致。而这时我们强制设置了预览的区域,这就会造成预览画面被拉伸。
知道了被拉伸的原因,那也就知道了解决方案,将图片等比例进行缩放就可以实现预览界面不被拉伸.
方案一
看下面gif图,就懂了吧,等比拉伸就可以100%实现全屏。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public void cameraHasOpened() { DisplayMetrics metrics = new DisplayMetrics(); mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels; int height = metrics.heightPixels;
if (camera != null) { Size size = camera.getParameters().getPreviewSize(); width = (int) (1.0F * height * size.width / size.height); float scale = screenWidth / (width * 1.0f); width = screenWidth; height = (int)(screenHeight * scale); } FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(width, height, Gravity.CENTER); mCameraView.setLayoutParams(lParams); }
|
方案二
从相机硬件提供的众多预览尺寸中找到一个尽可能匹配到一个合适的尺寸,算法如下。
但是不一定能保证选出来的一定就是刚好与屏幕尺寸完全相同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| private static Point findBestPreviewSizeValue(List<Camera.Size> sizes, int screenWidth, int screenHeight) { int bestX = 0; int bestY = 0; int diff = Integer.MAX_VALUE; for (Camera.Size size : sizes) { int dimPosition = size.width; if (dimPosition < 0) { continue; } int newDiff = Math.abs(size.width - screenWidth) + Math.abs(size.height - screenHeight); if (newDiff == 0) { bestX = size.width; bestY = size.height; break; } else if (newDiff < diff) { bestX = size.width; bestY = size.height; diff = newDiff; } } if (bestX > 0 && bestY > 0) { return new Point(bestX, bestY); } return null; }
|
参考
高仿微信Android自定义全屏相机