35 拍照流程实现:CaptureSession 管理与照片保存 35 拍照流程实现CaptureSession 管理与照片保存前言图35 拍照流程实现CaptureSession 管理与照片保存 运行效果截图HarmonyOS NEXT在 Camera Kit 中拍照流程的核心是CaptureSession——它负责管理相机输入、预览输出和拍照输出之间的数据流转。一个完整的拍照流程包括创建会话、配置输入输出、触发拍照和保存照片文件。本文以 “鹿鹿·笔迹心理分析” [CapturePage.ets](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/pages/CapturePage.ets) 中的拍照方法takePhoto()为主线深入解析 CaptureSession 的配置和照片文件的保存流程。鸿蒙官方·拍照开发指南developer.huawei.com项目源码仓库harmony-app GitHub图CaptureSession 管理——从创建会话到照片保存的完整数据流文件系统PhotoOutputCaptureSessionCameraManagerCapturePage文件系统PhotoOutputCaptureSessionCameraManagerCapturePagecreateCameraInput(device)createPreviewOutput(surface)createPhotoOutput(surface)beginConfig()addInput(cameraInput)addOutput(previewOutput)addOutput(photoOutput)commitConfig()start()capture(settings)onPhotoAvailable 回调写入图片文件一、拍照的完整流程1.1 七大步骤privateasynctakePhoto(){this.isCapturingtruetry{// Step 1: 获取相机管理器constcameraManagercamera.getCameraManager(getContext(this)ascommon.Context)// Step 2: 获取相机设备constcamerascameraManager.getSupportedCameras()constcameraDevicecameras[0]// 使用第一个可用相机通常为后置// Step 3: 创建 CaptureSessionconstsessioncameraManager.createCaptureSession(cameraDevice)awaitsession.beginConfig()// Step 4: 添加相机输入constcameraInputcameraManager.createCameraInput(cameraDevice)awaitcameraInput.open()session.addInput(cameraInput)// Step 5: 添加预览输出surfaceconstpreviewSurfacethis.surfaceIdconstpreviewOutputcameraManager.createPreviewOutput(previewSurface)session.addOutput(previewOutput)// Step 6: 添加拍照输出constphotoOutputcameraManager.createPhotoOutput()session.addOutput(photoOutput)// 提交配置awaitsession.commitConfig()awaitsession.start()// Step 7: 拍照 保存文件constphotoFilefs.openSync(/data/storage/el2/base/cache/capture_${Date.now()}.jpg,fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE)awaitphotoOutput.capture(photoFile.fd)this.previewPathphotoFile.paththis.hasPreviewtruefs.closeSync(photoFile)}catch(error){hilog.error(0x0000,TAG,拍照失败: %s,JSON.stringify(error))}finally{this.isCapturingfalse}}1.2 项目中的调试简化// 项目当前使用调试模式模拟拍照privateasynctakePhoto(){this.isCapturingtruetry{awaitnewPromisevoid(resolvesetTimeout(resolve,500))this.previewPath/data/storage/el2/base/cache/capture_${Date.now()}.jpgthis.hasPreviewtrue}finally{this.isCapturingfalse}}提示完整拍照流程依赖真机的相机硬件支持。在开发调试阶段使用 setTimeout 模拟延时是一个常见的降级策略。二、CaptureSession 的关键概念2.1 beginConfig / commitConfigCaptureSession采用配置-提交模式方法说明调用时机beginConfig()开始配置会话添加/移除输出之前addInput(input)添加相机输入源beginConfig 之后addOutput(output)添加输出目标beginConfig 之后removeOutput(output)移除输出beginConfig 之后commitConfig()提交配置所有配置完成后start()启动会话commitConfig 之后stop()停止会话暂停预览时release()释放会话页面销毁时2.2 配置的生命周期beginConfig() ↓ 会话进入可配置状态 addInput() / addOutput() ↓ 可以多次添加 commitConfig() ↓ 配置锁定 start() ↓ 会话开始运行拍照/预览 stop() ↓ 会话暂停 beginConfig() (再次) ↓ 切换摄像头等需要重新配置 commitConfig() ↓ start() ↓ release() ↓ 会话销毁三、输入与输出3.1 CameraInput相机输入// 创建相机输入constcameraInputcameraManager.createCameraInput(cameraDevice)awaitcameraInput.open()// 添加到会话session.addInput(cameraInput)// 关闭cameraInput.close()3.2 PreviewOutput预览输出// 预览需要 XComponent 提供的 surfaceId// 在 UI 中定义取景 Surface// XComponent({ id: cameraXComponent, type: surface, ... })// 创建预览输出constpreviewOutputcameraManager.createPreviewOutput(previewSurface)session.addOutput(previewOutput)3.3 PhotoOutput拍照输出// 创建拍照输出constphotoOutputcameraManager.createPhotoOutput()session.addOutput(photoOutput)// 捕获照片 → 保存到文件awaitphotoOutput.capture(fileDescriptor)四、照片文件保存4.1 使用 fileIo 保存import{fileIoasfs}fromkit.CoreFileKit// 打开/创建文件constphotoFilefs.openSync(/data/storage/el2/base/cache/capture_${Date.now()}.jpg,fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE)// 拍照写入文件awaitphotoOutput.capture(photoFile.fd)// 关闭文件fs.closeSync(photoFile)4.2 文件名策略// 生成唯一文件名consttimestampDate.now()constfileNamecapture_${timestamp}.jpg// 示例capture_1712345678900.jpgconstfilePath/data/storage/el2/base/cache/${fileName}4.3 文件保存位置路径说明用途/data/storage/el2/base/cache/应用缓存目录临时文件/data/storage/el2/base/files/应用文件目录持久文件相册photoAccessHelper持久用户可见五、拍照后处理5.1 确认使用// 确认使用照片privateconfirmPhoto(){// 保存照片路径到全局状态AppStorage.setOrCreatestring(capture_image_path,this.previewPath)// 跳转分析页面this.getUIContext().getRouter().pushUrl({url:pages/AnalyzingPage,params:{imagePath:this.previewPath}})}5.2 重拍privateretake(){this.hasPreviewfalsethis.previewPath// 相机重新进入取景模式}5.3 完整交互流程用户进入 CapturePage ↓ 取景模式实时预览 ↓ 用户点击拍照按钮 ↓ isCapturing true拍照中... ↓ photoOutput.capture(fd) → 文件保存 ↓ hasPreview true进入预览模式 ↓ ┌── 用户选择确认使用 → 跳转 AnalyzingPage └── 用户选择重拍 → hasPreview false回到取景六、拍照页面的 UI 结构6.1 分屏状态CapturePage 的 UI 分为两种状态build(){Column(){// 状态栏// 顶部栏关闭 自动模式if(!this.hasPreview){// 取景模式提示文字 取景框 四角引导 示例文字}else{// 预览模式显示拍摄预览}if(!this.hasPreview){// 底部操作区相册按钮 拍照按钮 翻转按钮}else{// 底部操作区重拍按钮 确认使用按钮}}}6.2 取景框设计取景框使用 Stack 虚线框 四角引导 示例文字的组合Stack(){Column().width(260).height(340).border({width:2,color:rgba(247,243,236,0.7),style:BorderStyle.Dashed}).borderRadius(18).scale({x:this.pulseScale,y:this.pulseScale}).opacity(this.pulseOpacity)// 四角引导框// 左上角 border: { left: 3, top: 3 }, radius: { topLeft: 8 }// 右上角 border: { right: 3, top: 3 }, radius: { topRight: 8 }// ...Text(今天天气真好\n想去看看海\n心里很安静).fontSize(18).fontFamily(AppFonts.SERIF).fontColor(rgba(255,255,255,0.55)).rotate({angle:-2})}七、拍照流程调试7.1 日志追踪hilog.info(0x0000,TAG,拍照成功: %{public}s,this.previewPath)hilog.error(0x0000,TAG,拍照失败: %{public}s,JSON.stringify(error))7.2 常见错误错误信息原因解决session.beginConfig()失败Session 已被 release检查资源释放时序cameraInput.open()超时相机设备被占用确保之前会话已 releasephotoOutput.capture()失败fd 无效检查文件路径和权限surfaceId 无效XComponent 未就绪使用onReady回调后再获取八、拍照性能优化8.1 拍照按钮防重复StateisCapturing:booleanfalse// 拍照时禁用按钮Circle().fill(AppColors.WARM).opacity(this.isCapturing?0.5:1.0).enabled(!this.isCapturing).onClick(()this.takePhoto())8.2 异步处理所有相机操作都是异步的使用async/await管理流程privateasynctakePhoto(){this.isCapturingtruetry{// await 每一步操作awaitthis.initCamera()awaitsession.beginConfig()// ...}finally{this.isCapturingfalse}}总结本文深入解析了鸿蒙 Camera Kit 的拍照流程实现CaptureSession 配置beginConfig → addInput/addOutput → commitConfig → start输入输出管理CameraInput输入 PreviewOutput预览 PhotoOutput拍照照片保存photoOutput.capture(fd) fileIo 文件操作流程控制取景模式 ↔ 预览模式拍照状态isCapturing防重复UI 交互两段式底部栏拍照态 vs 预览态 确认/重拍下一篇文章将介绍图像预处理与裁剪——拍照后的图片处理流程。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力参考资源Camera Kit 拍照开发指南CaptureSession 管理[CapturePage 项目源码](file:///Users/fiona/Downloads/bijixinli/harmony-app/entry/src/main/ets/pages/CapturePage.ets)fileIo 文件读写kit.CoreFileKit 模块PhotoOutput.capture APIHarmonyOS 开发文档