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

相关文章

使用Python实现获取网页指定内容

《使用Python实现获取网页指定内容》在当今互联网时代,网页数据抓取是一项非常重要的技能,本文将带你从零开始学习如何使用Python获取网页中的指定内容,希望对大家有所帮助... 目录引言1. 网页抓取的基本概念2. python中的网页抓取库3. 安装必要的库4. 发送HTTP请求并获取网页内容5. 解

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息

VSCode中C/C++编码乱码问题的两种解决方法

《VSCode中C/C++编码乱码问题的两种解决方法》在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码,这种编码不一致会导致在VSC... 目录问题方法一:通过 Code Runner 插件调整编码配置步骤方法二:在 PowerShell

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的