4-4.Andorid Camera 之简化编码模板(获取摄像头 ID、选择最优预览尺寸)

本文主要是介绍4-4.Andorid Camera 之简化编码模板(获取摄像头 ID、选择最优预览尺寸),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、Camera 简化思路

  1. 在 Camera 的开发中,其实我们通常只关注打开相机、图像预览和关闭相机,其他的步骤我们不应该花费太多的精力

  2. 为此,应该提供一个工具类,它有处理相机的一些基本工具方法,包括获取摄像头 ID、选择最优预览尺寸以及打印相机参数信息


二、Camera 工具类

  • CameraIdResult.java
public class CameraIdResult {private int qzCameraId = -1; // 前置摄像头 idprivate int hzCameraId = -1; // 后置摄像头 idpublic CameraIdResult() {}public CameraIdResult(int qzCameraId, int hzCameraId) {this.qzCameraId = qzCameraId;this.hzCameraId = hzCameraId;}public int getQzCameraId() {return qzCameraId;}public void setQzCameraId(int qzCameraId) {this.qzCameraId = qzCameraId;}public int getHzCameraId() {return hzCameraId;}public void setHzCameraId(int hzCameraId) {this.hzCameraId = hzCameraId;}
}
  • MyCameraTool.java
public class MyCameraTool {public static final String TAG = MyCameraTool.class.getSimpleName();/*** 得到摄像头 Id 对象** @return 摄像头 Id 对象,它有前置摄像头 Id 和后置摄像头 Id*/public static CameraIdResult getCameraIdResult() {CameraIdResult cameraIdResult = new CameraIdResult();int numberOfCameras = Camera.getNumberOfCameras();Log.i(TAG, "------------------------------ 摄像头个数:" + numberOfCameras);for (int cameraId = 0; cameraId < numberOfCameras; cameraId++) {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();Camera.getCameraInfo(cameraId, cameraInfo);if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {Log.i(TAG, "------------------------------ 前置摄像头,cameraId 为:" + cameraId);cameraIdResult.setQzCameraId(cameraId);}if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {Log.i(TAG, "------------------------------ 后置摄像头,cameraId 为:" + cameraId);cameraIdResult.setHzCameraId(cameraId);} else {Log.i(TAG, "------------------------------ 其他摄像头,cameraId 为:" + cameraId);}}return cameraIdResult;}/*** 根据 SurfaceView 的尺寸和相机支持的预览尺寸来选择最优的预览尺寸** @param sizes 相机支持的预览尺寸列表* @param w     SurfaceView 的宽度* @param h     SurfaceView 的高度* @return 最优的预览尺寸,如果没有合适的尺寸则返回 null*/public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {if (sizes == null) return null;final double ASPECT_TOLERANCE = 0.1;double targetRatio = (double) h / w;Camera.Size optimalSize = null;double minDiff = Double.MAX_VALUE;int targetHeight = h;// 遍历所有支持的预览尺寸for (Camera.Size size : sizes) {// 检查宽高比是否接近目标宽高比double ratio = (double) size.width / size.height;if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;// 计算当前尺寸与目标尺寸的宽度差异// 如果差异小于当前最小差异,则更新最优尺寸和最小差异if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}// 如果找不到接近目标宽高比的尺寸,则选择最接近目标高度的尺寸if (optimalSize == null) {minDiff = Double.MAX_VALUE;for (Camera.Size size : sizes) {if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}}return optimalSize;}/*** 打印相机参数信息** @param parameters 相机参数对象*/public static void showParameters(Camera.Parameters parameters) {Camera.Size previewSize = parameters.getPreviewSize();Log.i(TAG, "============================== getPreviewSize");Log.i(TAG, "---------- " + previewSize.width + " - " + previewSize.height);List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();Log.i(TAG, "============================== supportedPreviewSizes");Log.i(TAG, "============================== supportedPreviewSizes size: " + supportedPreviewSizes.size());for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {Log.i(TAG, "---------- " + supportedPreviewSize.width + " - " + supportedPreviewSize.height);}Camera.Size pictureSize = parameters.getPictureSize();Log.i(TAG, "============================== getPictureSize");Log.i(TAG, "---------- " + pictureSize.width + " - " + pictureSize.height);List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();Log.i(TAG, "============================== getSupportedPictureSizes");Log.i(TAG, "============================== getSupportedPictureSizes: " + supportedPictureSizes.size());for (Camera.Size supportedPictureSize : supportedPictureSizes) {Log.i(TAG, "---------- " + supportedPictureSize.width + " - " + supportedPictureSize.height);}String focusMode = parameters.getFocusMode();Log.i(TAG, "============================== getFocusMode");Log.i(TAG,"---------- " + focusMode);String whiteBalance = parameters.getWhiteBalance();Log.i(TAG, "============================== getWhiteBalance");Log.i(TAG,"---------- " + whiteBalance);int exposureCompensation = parameters.getExposureCompensation();Log.i(TAG, "============================== getExposureCompensation");Log.i(TAG,"---------- " + exposureCompensation);String flashMode = parameters.getFlashMode();Log.i(TAG, "============================== getFlashMode");Log.i(TAG,"---------- " + flashMode);}
}

三、Camera 工具类解析

1、获取取摄像头 ID
  1. 该方法用于获取取摄像头 ID,它会返回一个 cameraIdResult 对象

  2. cameraIdResult 对象有两个属性为 qzCameraId 和 hzCameraId,分别代表前置摄像头 ID 和后置摄像头 ID,如果 qzCameraId 或 hzCameraId 的值为 -1,代表没有获取到

public static CameraIdResult getCameraIdResult() {CameraIdResult cameraIdResult = new CameraIdResult();int numberOfCameras = Camera.getNumberOfCameras();Log.i(TAG, "------------------------------ 摄像头个数:" + numberOfCameras);for (int cameraId = 0; cameraId < numberOfCameras; cameraId++) {Camera.CameraInfo cameraInfo = new Camera.CameraInfo();Camera.getCameraInfo(cameraId, cameraInfo);if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {Log.i(TAG, "------------------------------ 前置摄像头,cameraId 为:" + cameraId);cameraIdResult.setQzCameraId(cameraId);}if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {Log.i(TAG, "------------------------------ 后置摄像头,cameraId 为:" + cameraId);cameraIdResult.setHzCameraId(cameraId);} else {Log.i(TAG, "------------------------------ 其他摄像头,cameraId 为:" + cameraId);}}return cameraIdResult;
}
2、选择最优预览图像尺寸
  • 该方法用于选择最优预览图像尺寸,设置最优预览图像尺寸,能保证在预览图像时(例如,SurfaceView)图像不被拉伸
public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {if (sizes == null) return null;final double ASPECT_TOLERANCE = 0.1;double targetRatio = (double) h / w;Camera.Size optimalSize = null;double minDiff = Double.MAX_VALUE;int targetHeight = h;// 遍历所有支持的预览尺寸for (Camera.Size size : sizes) {// 检查宽高比是否接近目标宽高比double ratio = (double) size.width / size.height;if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;// 计算当前尺寸与目标尺寸的宽度差异// 如果差异小于当前最小差异,则更新最优尺寸和最小差异if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}// 如果找不到接近目标宽高比的尺寸,则选择最接近目标高度的尺寸if (optimalSize == null) {minDiff = Double.MAX_VALUE;for (Camera.Size size : sizes) {if (Math.abs(size.height - targetHeight) < minDiff) {optimalSize = size;minDiff = Math.abs(size.height - targetHeight);}}}return optimalSize;
}
3、打印相机参数信息
  • 该方法用于打印相机参数信息,用于了解设备,并根据业务做更合适的设置
  1. 例如,根据 supportedPreviewSizes 可以对预览图像的大小做更合适的设置(SurfaceView、setPreviewSize 方法)

  2. 再例如,根据 getSupportedPictureSizes 可以对拍照时图片的大小做更合适的设置(setPictureSize 方法)

public static void showParameters(Camera.Parameters parameters) {Camera.Size previewSize = parameters.getPreviewSize();Log.i(TAG, "============================== getPreviewSize");Log.i(TAG, "---------- " + previewSize.width + " - " + previewSize.height);List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();Log.i(TAG, "============================== supportedPreviewSizes");Log.i(TAG, "============================== supportedPreviewSizes size: " + supportedPreviewSizes.size());for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {Log.i(TAG, "---------- " + supportedPreviewSize.width + " - " + supportedPreviewSize.height);}Camera.Size pictureSize = parameters.getPictureSize();Log.i(TAG, "============================== getPictureSize");Log.i(TAG, "---------- " + pictureSize.width + " - " + pictureSize.height);List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();Log.i(TAG, "============================== getSupportedPictureSizes");Log.i(TAG, "============================== getSupportedPictureSizes: " + supportedPictureSizes.size());for (Camera.Size supportedPictureSize : supportedPictureSizes) {Log.i(TAG, "---------- " + supportedPictureSize.width + " - " + supportedPictureSize.height);}String focusMode = parameters.getFocusMode();Log.i(TAG, "============================== getFocusMode");Log.i(TAG,"---------- " + focusMode);String whiteBalance = parameters.getWhiteBalance();Log.i(TAG, "============================== getWhiteBalance");Log.i(TAG,"---------- " + whiteBalance);int exposureCompensation = parameters.getExposureCompensation();Log.i(TAG, "============================== getExposureCompensation");Log.i(TAG,"---------- " + exposureCompensation);String flashMode = parameters.getFlashMode();Log.i(TAG, "============================== getFlashMode");Log.i(TAG,"---------- " + flashMode);
}

这篇关于4-4.Andorid Camera 之简化编码模板(获取摄像头 ID、选择最优预览尺寸)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147791

相关文章

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取

C/C++通过IP获取局域网网卡MAC地址

《C/C++通过IP获取局域网网卡MAC地址》这篇文章主要为大家详细介绍了C++如何通过Win32API函数SendARP从IP地址获取局域网内网卡的MAC地址,感兴趣的小伙伴可以跟随小编一起学习一下... C/C++通过IP获取局域网网卡MAC地址通过win32 SendARP获取MAC地址代码#i

5分钟获取deepseek api并搭建简易问答应用

《5分钟获取deepseekapi并搭建简易问答应用》本文主要介绍了5分钟获取deepseekapi并搭建简易问答应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需... 目录1、获取api2、获取base_url和chat_model3、配置模型参数方法一:终端中临时将加

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Python MySQL如何通过Binlog获取变更记录恢复数据

《PythonMySQL如何通过Binlog获取变更记录恢复数据》本文介绍了如何使用Python和pymysqlreplication库通过MySQL的二进制日志(Binlog)获取数据库的变更记录... 目录python mysql通过Binlog获取变更记录恢复数据1.安装pymysqlreplicat

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出