Android Camera2 拉伸问题

匿名 (未验证) 提交于 2019-12-03 00:27:02

Camera2在一些低端机器上出现拉伸问题,当然首先排除不是笔者低级错误设置的分辨率有问题。

Camera2在某些机型上画面拉伸,表象是我们设置16:9的输出(当然是查询到支持的分辨率),但是Camera实际输出的是4:3。
整个过程如下:

  1. 获取Camera支持的输出分辨率

                StreamConfigurationMap streamConfigurationMap = cameraInfo.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);         outputSizes = streamConfigurationMap.getOutputSizes(SurfaceTexture.class);         getBestMatchCameraPreviewSize(outputSizes);

    笔者选取oppo a37f为例,其支持的分辨率如下:

  2. 选择适合的分辨率

      public static TESizei getClosestSupportedSize(   List<TESizei> supportedSizes, final int requestedWidth, final int requestedHeight) { return Collections.min(supportedSizes, new ClosestComparator<TESizei>() {   @Override   int diff(TESizei size) {     return abs(requestedWidth - size.width) + abs(requestedHeight - size.height);   } }); }

    笔者选取1280x720分辨率,这个在上面列表中是支持的。

  3. 开始预览
    这个时候就坑了,画面被拉伸了。通过Log发现,Camera实际输出的是1280x960的图像。更加坑爹的是,没有接口获取Camera真正输出的分辨率。日志如下:

    242 06-06 12:59:50.875  7451  8170 E Camera  : setPreviewSize(), mPackageName = xxxxxxx , width = 1280 , height = 960

看看吧,这个坑货,说是支持720P,设置也成功了,但是输出是1280x960!!

Google后发现这个问题还是相当普遍的,笔者就在Stack Overflow上找到相同的提问,但是并没有解决这个问题:
Camera2 Preview Stretching

后来笔者在WebRtc中发现关于这个问题的说明:

> Video may be stretched pre LMR1 on legacy implementations. Filter out formats that have different aspect ratio than the sensor array.  也就是说在android 5.0,硬件兼容级别为legacy时,Camera2输出的宽高比和Camera Sensor保持一致。**好吧,我们算是找到原因了,但是并没有彻底解决问题,因为我的oppo a37f是5.1.1系统!!!WTF!!!!** 
      public static List<Size> getSupportedSizes(CameraCharacteristics cameraCharacteristics) {     final StreamConfigurationMap streamMap =         cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);     final int supportLevel =         cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);      final android.util.Size[] nativeSizes = streamMap.getOutputSizes(SurfaceTexture.class);     final List<Size> sizes = convertSizes(nativeSizes);      // Video may be stretched pre LMR1 on legacy implementations.     // Filter out formats that have different aspect ratio than the sensor array.     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1         && supportLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {       final Rect activeArraySize =           cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);       final ArrayList<Size> filteredSizes = new ArrayList<Size>();        for (Size size : sizes) {         if (activeArraySize.width() * size.height == activeArraySize.height() * size.width) {           filteredSizes.add(size);         }       }        return filteredSizes;     } else {       return sizes;     }   }

CameraView简单粗暴,硬件兼容为LEGACY直接切到Camera1.

            // Not found             mCameraId = ids[0];             mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);             Integer level = mCameraCharacteristics.get(                     CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);             if (level == null ||                     level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {                 return false;             }

[1] WebRTC
[2] CameraView

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!