关于自定义相机预览界面拉伸问题

关于自定义相机预览界面拉伸问题

  • 导致主要变形的原因是Camera预览界面旋转的角度和摄像头挂载的角度不同导致的
  • 我们的Activity设置的方向是竖屏,这是手机的自然方向 所以宽比高短
  • 角度:所谓屏幕和摄像头的角度,指的是相对于自然方向旋转过的角度,根据旋转角度即可获知当前的方向
  • 假如说:手机是竖屏的情况下, 自然角度为0,但是Camera逆时针旋转90度,那咱们设置顺时针旋转90度,就正常 。手机是横屏的情况下Camera返回为0度 ,如果设置顺时针旋转90度,就回旋转

怎么设置预览界面与实景保持一致的方法,官方给出的文档:

public static void setCameraDisplayOrientation(Activity activity,int cameraIo, Camera camera){

Camera.CameraInfo info=new Camera.CameraInfo();
Camera.getCameraInfo(cameraIo,info);
int rotation=activity.getWindowManager().getDefaultDisplay().getRotation();
int degress=0;
switch(rotation){
case Surface.ROTATION_0:
     degress=0;
     break;
case Surface.ROTATION_90:
     degress=90;
     break;
 case Surface.ROTATION_180:
     degress=180;
     break;
case Surface.ROTATION_270:
     degress=270;
     break;
}
int result;
if(info.facing=Camera.CameraInfo.CAMERA_FACING_FRONT){
   result = (info.orientation + degrees) % 360;
   > 就是摄像头需要顺时针转过多少度才能恢复自然方向
   result = (360 - result) % 360;
   } else {  // back-facing
    result = (info.orientation - degrees + 360) % 360;
   }
   camera.setDisplayOrientation(result);
switch (result) {
     case 0:
     case 180:
     setCameraSize(camera.getParameters(),                      getScreenWidth(), getScreenHeight());
        break;
      case 90:
      case 270:
     setCameraSize(camera.getParameters(),                      getScreenHeight(), getScreenWidth());
            break;
}
}

public static void setCameraSize(Camera.Parameters parameters, int width, int height) {
        Map> allSizes = new HashMap<>();
        String typePreview = "typePreview";
        String typePicture = "typePicture";
        allSizes.put(typePreview, parameters.getSupportedPreviewSizes());
        allSizes.put(typePicture, parameters.getSupportedPictureSizes());
        Iterator iterator = allSizes.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry> entry = (Map.Entry>) iterator.next();
            List sizes = entry.getValue();
            if (sizes == null || sizes.isEmpty()) continue;
            ArrayList wrapCameraSizes = new ArrayList<>(sizes.size());
            for (Size size : sizes) {
                WrapCameraSize wrapCameraSize = new WrapCameraSize();
                wrapCameraSize.setWidth(size.width);
                wrapCameraSize.setHeight(size.height);
                wrapCameraSize.setD(Math.abs((size.width - width)) + Math.abs((size.height - height)));
                if (size.width == width && size.height == height) {
                    if (typePreview.equals(entry.getKey())) {
                        parameters.setPreviewSize(size.width, size.height);
                    } else if (typePicture.equals(entry.getKey())) {
                        parameters.setPictureSize(size.width, size.height);
                    }
                    Log.d(TAG, "best size: width=" + size.width + ";height=" + size.height);
                    break;
                }
                wrapCameraSizes.add(wrapCameraSize);
            }
            Log.d(TAG, "wrapCameraSizes.size()=" + wrapCameraSizes.size());
            Size resultSize = null;
            if (typePreview.equals(entry.getKey())) {
                resultSize = parameters.getPreviewSize();
            } else if (typePicture.equals(entry.getKey())) {
                resultSize = parameters.getPictureSize();
            }
            if (resultSize == null || (resultSize.width != width && resultSize.height != height)) {
                //找到相机Preview Size 和 Picture Size中最适合的大小
                if(wrapCameraSizes.isEmpty()) continue;
                WrapCameraSize minCameraSize = Collections.min(wrapCameraSizes);
                while (!(minCameraSize.getWidth() >= width && minCameraSize.getHeight() >= height)) {
                    wrapCameraSizes.remove(minCameraSize);
                    if(wrapCameraSizes.isEmpty()) break;
                    minCameraSize = null;
                    minCameraSize = Collections.min(wrapCameraSizes);
                }
                Log.d(TAG, "best min size: width=" + minCameraSize.getWidth() + ";height=" + minCameraSize.getHeight());
                if (typePreview.equals(entry.getKey())) {
                    parameters.setPreviewSize(minCameraSize.getWidth(), minCameraSize.getHeight());
                } else if (typePicture.equals(entry.getKey())) {
                    parameters.setPictureSize(minCameraSize.getWidth(), minCameraSize.getHeight());
                }
            }
            iterator.remove();
        }
    }
  • 先将获取手机支持预览的尺寸列表通过parmeters.getSupportPreviewSize返回的是一个集合。
  • 进行屏幕方向的判断,因为预览的尺寸都是w>h 如果是竖屏,则需要将宽和高进行调换
  • 将预览尺寸列表的每个元素的宽和高与SurfaceView的宽和高进行比较,如果存在宽和高尺寸SurfaceView的宽和高,相同的size,则将当前的宽高设置为预览尺寸
  • 如果没有找到该步骤,则将尺寸列表的比例和SUrfaceView的比例做比较,找一个相同或者相近的 。

你可能感兴趣的:(关于自定义相机预览界面拉伸问题)