当前位置: 首页 > 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在后置相机预览时也没有被拉升。

http://www.xdnf.cn/news/961597.html

相关文章:

  • 《高等数学》(同济大学·第7版)第四章第二节换元积分法
  • 在GIS 工作流中实现数据处理
  • 天机学堂手撸
  • CentOS下的分布式内存计算Spark环境部署
  • 什么是MongoDB
  • freeCAD 学习 step1
  • 【FFmpeg学习(2)】视频概念
  • 雨季智慧交通:从车辆盲区到客流统计的算法全覆盖
  • ubuntu + nginx 1.26 + php7.4 + mysql8.0 调优
  • Cypher 查询语言完全指南(2024最新版)—— Neo4j 图数据库实战教程
  • Unity | AmplifyShaderEditor插件基础(第八集:噪声波动shader)
  • QT中实现tcp连接
  • MongoDB数据库应用
  • AO810 AO810V2 - ABB Ability系统800xA硬件
  • 校园导航系统核心技术解析:高精度定位与 AR 实景导航的应用实践
  • 【动作】AVA:时空定位原子视觉动作视频数据集
  • 【Dv3Admin】系统视图角色菜单按钮权限API文件解析
  • Doris “_stream_load“ 方式批量导入数据
  • Remmina远程访问如何开启本地音频?
  • (41)课60--61高级篇: MySQL体系结构(连接层、服务层、引擎层、存储层)。存储引擎是基于表的,可为不同表指定不同的存储引擎;查询表结构语句 show create table 表名
  • #Word“嵌入式”插图显示不全的解决教程
  • 在Word中使用 Microsoft Print to PDF和另存为PDF两种方式生成的 PDF文件
  • ubuntu24安装TensorRT
  • ubuntu24.04安装IDEA2025.1.2搭建java开发环境
  • 数据结构-链表OJ-回文链表,如何将时间复杂度控制为O(N),空间复杂度控制为O(1)?
  • POI设置Excel单元格背景色
  • DataFrame中.iloc 属性
  • HTAP 技术:融合事务与分析的数据处理新范式
  • 【数据篇】持久化核心:整合 JPA/MyBatis 实现优雅的数据库操作
  • pcie问答--0609