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

 更新时间:2022年05月19日 09:09:18   作者:doujiandong  
这篇文章主要为大家详细介绍了Android中关于自定义相机预览界面拉伸问题,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

1、导致主要变形的原因是Camera预览界面旋转的角度和摄像头挂载的角度不同导致的
2、我们的Activity设置的方向是竖屏,这是手机的自然方向 所以宽比高短
3、角度:所谓屏幕和摄像头的角度,指的是相对于自然方向旋转过的角度,根据旋转角度即可获知当前的方向
4、假如说:手机是竖屏的情况下, 自然角度为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<String, List<Size>> 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<String, List<Size>> entry = (Map.Entry<String, List<Size>>) iterator.next();
  List<Size> sizes = entry.getValue();
  if (sizes == null || sizes.isEmpty()) continue;
  ArrayList<WrapCameraSize> 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的比例做比较,找一个相同或者相近的 。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android项目实战之Glide 高斯模糊效果的实例代码

    Android项目实战之Glide 高斯模糊效果的实例代码

    这篇文章主要介绍了Android项目实战之Glide 高斯模糊效果的实例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-06-06
  • 浅谈Android studio 生成apk文件时的 key store path 的问题

    浅谈Android studio 生成apk文件时的 key store path 的问题

    这篇文章主要介绍了浅谈Android studio 生成apk文件时的 key store path 的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • 详解android与服务端交互的两种方式

    详解android与服务端交互的两种方式

    这篇文章主要介绍了详解android与服务端交互的两种方式,此处介绍两种方式:使用Google原生的Gson解析json数据,使用JSONObject解析json数据,有兴趣的可以了解一下
    2017-07-07
  • 详解adb工具的基本使用

    详解adb工具的基本使用

    adb全称Android Debug Bridge,是Android SDK中的一个工具, 使用adb可以直接操作管理Android模拟器或者真实的Andriod设备,就是起到调试桥的作用,这篇文章主要介绍了adb工具的基本使用,需要的朋友可以参考下
    2022-08-08
  • Android编程实现仿易信精美弹出框效果【附demo源码下载】

    Android编程实现仿易信精美弹出框效果【附demo源码下载】

    这篇文章主要介绍了Android编程实现仿易信精美弹出框效果,涉及Android窗口及动画操作相关技巧,并附带demo源码供读者下载参考,需要的朋友可以参考下
    2017-01-01
  • Flutter质感设计之直接输入

    Flutter质感设计之直接输入

    这篇文章主要为大家详细介绍了Flutter质感设计之直接输入,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Android2.3实现Android4.0风格EditText的方法

    Android2.3实现Android4.0风格EditText的方法

    这篇文章主要介绍了Android2.3实现Android4.0风格EditText的方法,涉及Android界面布局及控件调用的相关技巧,需要的朋友可以参考下
    2016-03-03
  • 一起动手编写Android图片加载框架

    一起动手编写Android图片加载框架

    这篇文章主要和大家一起动手编写Android图片加载框架,从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • Android解决getExternalStorageDirectory在29后废弃问题(推荐)

    Android解决getExternalStorageDirectory在29后废弃问题(推荐)

    这篇文章主要介绍了Android解决getExternalStorageDirectory在29后废弃问题(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Android实现相机拍摄、选择、图片裁剪功能

    Android实现相机拍摄、选择、图片裁剪功能

    自定义控件,重写ImageView 功能实现:点击圆形头像之后可以实现相册上传或者开启相机,然后把得到的图片经过剪裁,把剪裁过的图片设置为头像的背景图,需要的朋友可以参考下
    2016-09-09

最新评论