10) CaptureResult
CaptureResult 是每一次 Capture 操作的结果,里面包括了很多状态信息,包括闪光灯状态、对焦状态、时间戳等等 。
例如你可以在拍照完成的时候,通过 CaptureResult 获取本次拍照时的对焦状态和时间戳 。
需要注意的是,CaptureResult 并不包含任何图像数据,前面我们在介绍 Surface 的时候说了,图像数据都是从 Surface 获取的 。
11) Request的整体处理流程
三、 代码实战:如何拍摄单张照片
拍摄单张照片是最简单的拍照模式,它使用的就是 单次模式 的 Capture,我们会使用 ImageReader 创建一个接收照片的 Surface,并且把它添加到 CaptureRequest 里提交给相机进行拍照,最后通过 ImageReader 的回调获取 Image 对象,进而获取 JPEG 图像数据进行保存 。
1) 定义回调接口
当拍照完成的时候我们会得到两个数据对象,一个是通过 onImageAvailable() 回调给我们的存储图像数据的 Image,一个是通过 onCaptureCompleted() 回调给我们的存储拍照信息的 CaptureResult,它们是一一对应的,所以我们定义了如下两个回调接口:
private val captureResults: BlockingQueue<CaptureResult> = LinkedBlockingDeque()private inner class CaptureImageStateCallback : CameraCaptureSession.CaptureCallback() {@MainThreadoverride fun onCaptureCompleted(session: CameraCaptureSession, request: CaptureRequest, result: TotalCaptureResult) {super.onCaptureCompleted(session, request, result)captureResults.put(result)}}private inner class OnJpegImageAvailableListener : ImageReader.OnImageAvailableListener {@WorkerThreadoverride fun onImageAvailable(imageReader: ImageReader) {val image = imageReader.acquireNextImage()val captureResult = captureResults.take()if (image != null && captureResult != null) {// Save image into sdcard.}}}2) 创建 ImageReader
创建 ImageReader 需要我们指定照片的大小,所以首先我们要获取支持的照片尺寸列表,并且从中筛选出合适的尺寸,假设我们要求照片的尺寸最大不能超过 4032×3024,并且比例必须是 4:3,所以会有如下筛选尺寸的代码片段:
@WorkerThreadprivate fun getOptimalSize(cameraCharacteristics: CameraCharacteristics, clazz: Class<*>, maxWidth: Int, maxHeight: Int): Size? {val streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)val supportedSizes = streamConfigurationMap?.getOutputSizes(clazz)return getOptimalSize(supportedSizes, maxWidth, maxHeight)}@AnyThreadprivate fun getOptimalSize(supportedSizes: Array<Size>?, maxWidth: Int, maxHeight: Int): Size? {val aspectRatio = maxWidth.toFloat() / maxHeightif (supportedSizes != null) {for (size in supportedSizes) {if (size.width.toFloat() / size.height == aspectRatio && size.height <= maxHeight && size.width <= maxWidth) {return size}}}return null}接着我们就可以筛选出合适的尺寸,然后创建一个图像格式是 JPEG 的 ImageReader 对象,并且获取它的 Surface:
val imageSize = getOptimalSize(cameraCharacteristics, ImageReader::class.java, maxWidth, maxHeight)!!jpegImageReader = ImageReader.newInstance(imageSize.width, imageSize.height, ImageFormat.JPEG, 5)jpegImageReader?.setOnImageAvailableListener(OnJpegImageAvailableListener(), cameraHandler)jpegSurface = jpegImageReader?.surface3) 创建 CaptureRequest
接下来我们使用 TEMPLATE_STILL_CAPTURE 模板创建一个用于拍照的 CaptureRequest.Builder 对象,并且添加拍照的 Surface 和预览的 Surface 到其中:
captureImageRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE)captureImageRequestBuilder.addTarget(previewDataSurface)captureImageRequestBuilder.addTarget(jpegSurface)
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- win10获取system权限 windows虚机无法获取ip
- 苹果激活锁解除方法 appid没有权限
- 手机里面的nfc使用方法 nfc门禁卡模拟器免root
- 文件管理访问限制 查看文件夹权限命令
- 自带内存跑步听歌不用带手机 跑步不用带手机也能听歌
- win10自带系统迁移工具 win10迁移到固态硬盘详细教程
- dnf端口辅助免费权限 dnf端口辅助什么意思
- 免root状态栏美化神器 android状态栏尺寸
- 获取管理员权限win10的步骤 win10提升管理员权限的方法
- linux普通用户修改root密码 linux修改root密码命令