当前位置: 首页 > news >正文

关于Android camera2预览变形的坑

问题描述:

camera2使用后置摄像头预览时,预览画面被拉升。

分析:

获取camera前后摄像头id

private void cameraList(Context context) {cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);CameraCharacteristics characteristics = null;try {for (String cameraId : cameraManager.getCameraIdList()) {log("cameraId = " + cameraId);characteristics = cameraManager.getCameraCharacteristics(cameraId);if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_BACK) {mBackCameraId = cameraId;} else if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraMetadata.LENS_FACING_FRONT) {mFontCameraId = cameraId;}}if (mBackCameraId != null) {mCameraId = mBackCameraId;} else if (mFontCameraId != null) {mCameraId = mFontCameraId;}} catch (CameraAccessException e) {e.printStackTrace();}if (characteristics != null) {StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);Size[] sizes = map.getOutputSizes(SurfaceTexture.class);if (sizes != null && sizes.length > 0) {
//                for (Size size : mPreviewSize) {
//                    log("size = " + size.toString());
//                }mPreviewSize = getBestSize(sizes);if (mPreviewSize != null) {log("bestSize = " + mPreviewSize.toString());}}}log("mCameraId = " + mCameraId);}

设置预览尺寸

public void setBestSize(SurfaceView surfaceView) {if (cameraManager == null) {return;}CameraCharacteristics characteristics = null;try {characteristics = cameraManager.getCameraCharacteristics(mCameraId);} catch (CameraAccessException e) {e.printStackTrace();}if (characteristics != null) {StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);Size[] sizes = map.getOutputSizes(SurfaceTexture.class);if (sizes != null && sizes.length > 0) {Point relPoint = new Point();context.getDisplay().getRealSize(relPoint);mPreviewSize = getBestSize(sizes);//, relPointif (mPreviewSize != null) {log("bestSize = " + mPreviewSize.toString());Point point = new Point();context.getDisplay().getRealSize(point);double ratio = (double) mPreviewSize.getHeight() / (double) mPreviewSize.getWidth();int phone_width = point.x;int phone_height = point.y;ViewGroup.LayoutParams layoutParams = surfaceView.getLayoutParams();if (((double) phone_width / (double) phone_height) < ratio) {layoutParams.width = (int) ((double) mPreviewSize.getHeight() / (double) mPreviewSize.getWidth() * phone_height);log("layoutParams.width = " + layoutParams.width);layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;} else {layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;layoutParams.height = (int) ((double) mPreviewSize.getWidth() / (double) mPreviewSize.getHeight() * phone_width);log("layoutParams.height = " + layoutParams.height);}surfaceView.setLayoutParams(layoutParams);}}}}
    private Size getBestSize(Size[] outputSizes) {Point point = new Point();context.getDisplay().getRealSize(point);log("point = " + point);int phone_width = point.x;int phone_height = point.y;for (Size size : outputSizes) {double ratio = (double) size.getHeight() / (double) size.getWidth();
//            double ratio = (double) size.getWidth() / (double) size.getHeight();int height = (int) (phone_width / ratio);if (height > phone_height) {} else {return size;}}return null;}

因为默认使用的后置摄像头预览,所以mCameraId = mBackCameraId,开始预览时预览画面被上下拉升。

修改了getBestSize方法,

public static Size getBestSize(Size[] outputSizes) {int minDiff = Integer.MAX_VALUE;float targetRatio = point.y * 1.0f / point.x;Size optimalSize = null;Point point = new Point();context.getDisplay().getRealSize(point);log("point = " + point);for (Size size : outputSizes) {log("size = " + size.toString());if (size.getWidth() > point.y && size.getHeight() > point.x) {float multipleW = size.getWidth() * 1.0f / point.y * 1.0f;float multipleH = size.getHeight() * 1.0f / point.x * 1.0f;if (multipleW == multipleH) {return size;}}if (size.getWidth() == point.y && size.getHeight() == point.x) {return size;}int diff = Math.abs((int) (targetRatio * size.getWidth()) - size.getHeight());log("diff = " + diff);if (diff < minDiff) {minDiff = diff;optimalSize = size;}}return optimalSize;}

预览画面没有变化,打印信息看着也没有问题

打印:
point = Point(720, 1280)
bestSize = 1920x1080
layoutParams.height = 1280

解决方案:

在测试只使用前置摄像头预览时,发现预览画面没有被拉升,查看打印信息

point = Point(720, 1280)
bestSize = 1600x1200
layoutParams.width = 960

bestSize返回不相同,后置相机和前置相机的Size[] sizes = map.getOutputSizes(SurfaceTexture.class);返回不一样。使用前置相机的Size在后置相机预览时也没有被拉升。

相关文章:

  • [创业之路-415]:经济学 - 价值、使用价值、交换价值的全面解析
  • MS9292+MS9332 HD/DVI转VGA转换器+HD环出带音频
  • HarmonyOS开发:设备管理使用详解
  • GISBox如何导入Revit格式的BIM数据?
  • Kotlin基础语法二
  • AI驱动下的商品详情API:2025年电商平台的智能化数据交互新趋势
  • <component :is=““>
  • 【C++】回调函数,是什么,怎么用?
  • iview组件库:关于分页组件的使用与注意点
  • Spring Boot 分层架构与数据流转详解
  • uniapp的请求封装,如何避免重复提交请求
  • php利用createSheet生成excel表格(控制行高列宽、文本自动换行及表头字体样式)
  • RestClient
  • 基于数字孪生的水厂可视化平台建设:架构与实践
  • 【python深度学习】Day 50 预训练模型+CBAM模块
  • Lighttpd 配置选项介绍
  • mysql教程笔记(四)-锁和innoDB存储引擎
  • 基于FPGA的PID算法学习———实现PI比例控制算法
  • 深度学习——简介
  • 【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
  • 闵行网站制作/网站如何优化排名软件
  • 外贸模板网站/台州网站优化公司
  • 建设永久网站/百度公司推广电话
  • 哈尔滨网站建设制作费用/上海百度移动关键词排名优化
  • 不改变网站怎么做关键词优化/销售外包
  • 哪个网站做ic外单好/天津提升专业关键词排名