欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2023-12-22 13:33:52
关于自定义相机预览界面拉伸问题 1、导致主要变形的原因是camera预览界面旋转的角度和摄像头挂载的角度不同导致的 2、我们的activity设置的方向是竖屏,这是手机...

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

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的比例做比较,找一个相同或者相近的 。

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

上一篇:

下一篇: