查看: 2370|回复: 0

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

发表于 2017-8-6 11:35:57

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

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

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

  1. public static void setCameraDisplayOrientation(Activity activity,int cameraIo, Camera camera){
  2. Camera.CameraInfo info=new Camera.CameraInfo();
  3. Camera.getCameraInfo(cameraIo,info);
  4. int rotation=activity.getWindowManager().getDefaultDisplay().getRotation();
  5. int degress=0;
  6. switch(rotation){
  7. case Surface.ROTATION_0:
  8. degress=0;
  9. break;
  10. case Surface.ROTATION_90:
  11. degress=90;
  12. break;
  13. case Surface.ROTATION_180:
  14. degress=180;
  15. break;
  16. case Surface.ROTATION_270:
  17. degress=270;
  18. break;
  19. }
  20. int result;
  21. if(info.facing=Camera.CameraInfo.CAMERA_FACING_FRONT){
  22. result = (info.orientation + degrees) % 360;
  23. > 就是摄像头需要顺时针转过多少度才能恢复自然方向
  24. result = (360 - result) % 360;
  25. } else { // back-facing
  26. result = (info.orientation - degrees + 360) % 360;
  27. }
  28. camera.setDisplayOrientation(result);
  29. switch (result) {
  30. case 0:
  31. case 180:
  32. setCameraSize(camera.getParameters(), getScreenWidth(), getScreenHeight());
  33. break;
  34. case 90:
  35. case 270:
  36. setCameraSize(camera.getParameters(), getScreenHeight(), getScreenWidth());
  37. break;
  38. }
  39. }
  40. public static void setCameraSize(Camera.Parameters parameters, int width, int height) {
  41. Map<String, List<Size>> allSizes = new HashMap<>();
  42. String typePreview = "typePreview";
  43. String typePicture = "typePicture";
  44. allSizes.put(typePreview, parameters.getSupportedPreviewSizes());
  45. allSizes.put(typePicture, parameters.getSupportedPictureSizes());
  46. Iterator iterator = allSizes.entrySet().iterator();
  47. while (iterator.hasNext()) {
  48. Map.Entry<String, List<Size>> entry = (Map.Entry<String, List<Size>>) iterator.next();
  49. List<Size> sizes = entry.getValue();
  50. if (sizes == null || sizes.isEmpty()) continue;
  51. ArrayList<WrapCameraSize> wrapCameraSizes = new ArrayList<>(sizes.size());
  52. for (Size size : sizes) {
  53. WrapCameraSize wrapCameraSize = new WrapCameraSize();
  54. wrapCameraSize.setWidth(size.width);
  55. wrapCameraSize.setHeight(size.height);
  56. wrapCameraSize.setD(Math.abs((size.width - width)) + Math.abs((size.height - height)));
  57. if (size.width == width && size.height == height) {
  58. if (typePreview.equals(entry.getKey())) {
  59. parameters.setPreviewSize(size.width, size.height);
  60. } else if (typePicture.equals(entry.getKey())) {
  61. parameters.setPictureSize(size.width, size.height);
  62. }
  63. Log.d(TAG, "best size: width=" + size.width + ";height=" + size.height);
  64. break;
  65. }
  66. wrapCameraSizes.add(wrapCameraSize);
  67. }
  68. Log.d(TAG, "wrapCameraSizes.size()=" + wrapCameraSizes.size());
  69. Size resultSize = null;
  70. if (typePreview.equals(entry.getKey())) {
  71. resultSize = parameters.getPreviewSize();
  72. } else if (typePicture.equals(entry.getKey())) {
  73. resultSize = parameters.getPictureSize();
  74. }
  75. if (resultSize == null || (resultSize.width != width && resultSize.height != height)) {
  76. //找到相机Preview Size 和 Picture Size中最适合的大小
  77. if(wrapCameraSizes.isEmpty()) continue;
  78. WrapCameraSize minCameraSize = Collections.min(wrapCameraSizes);
  79. while (!(minCameraSize.getWidth() >= width && minCameraSize.getHeight() >= height)) {
  80. wrapCameraSizes.remove(minCameraSize);
  81. if(wrapCameraSizes.isEmpty()) break;
  82. minCameraSize = null;
  83. minCameraSize = Collections.min(wrapCameraSizes);
  84. }
  85. Log.d(TAG, "best min size: width=" + minCameraSize.getWidth() + ";height=" + minCameraSize.getHeight());
  86. if (typePreview.equals(entry.getKey())) {
  87. parameters.setPreviewSize(minCameraSize.getWidth(), minCameraSize.getHeight());
  88. } else if (typePicture.equals(entry.getKey())) {
  89. parameters.setPictureSize(minCameraSize.getWidth(), minCameraSize.getHeight());
  90. }
  91. }
  92. iterator.remove();
  93. }
  94. }
复制代码

先将获取手机支持预览的尺寸列表通过parmeters.getSupportPreviewSize返回的是一个集合。
进行屏幕方向的判断,因为预览的尺寸都是w>h 如果是竖屏,则需要将宽和高进行调换。
将预览尺寸列表的每个元素的宽和高与SurfaceView的宽和高进行比较,如果存在宽和高尺寸SurfaceView的宽和高,相同的size,则将当前的宽高设置为预览尺寸。
如果没有找到该步骤,则将尺寸列表的比例和SUrfaceView的比例做比较,找一个相同或者相近的 。

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



回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条