diff --git a/zh-cn/application-dev/media/camera.md b/zh-cn/application-dev/media/camera.md new file mode 100644 index 0000000000000000000000000000000000000000..1eb7c19276b087ebec0985cafc649eec90aa4b2a --- /dev/null +++ b/zh-cn/application-dev/media/camera.md @@ -0,0 +1,442 @@ +# 相机开发指导 + +## 场景介绍 + +相机模块支持相机相关基础功能的开发,主要包括预览、拍照、录像等。本文将对相机各种基础功能的开发进行介绍说明。 + +## 开发步骤 + +### 接口说明 + +详细API含义请参考:[相机管理API文档](../reference/apis/js-apis-camera.md) + +### 全流程场景 + +包含流程:创建实例、参数设置、会话管理、拍照、录像、释放资源等。 + +Xcomponent创建方法可参考:[XComponent创建方法] + +#### XComponent创建方法 +预览画面显示需要获取SurfaceId + +```js +mXComponentController: XComponentController = new XComponentController //创建XComponentController + +build() { + Flex() { + XComponent({ //创建XComponent + id: '', + type: 'surface', + libraryname: '', + controller: this.mXComponentController + }) + .onload(() => { //设置onload回调 + //设置Surface宽高(1920*1080) + this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080}) + //获取Surface ID + globalThis.surfaceId = mXComponentController.getXComponentSurfaceId() + }) + .width('1920px') //设置XComponent宽度 + .height('1080px') //设置XComponent高度 + } +} +``` + +#### 创建实例 + +```js +import camera from '@ohos.mutimedia.camera' +import image from '@ohos.mutimedia.image' +import media from '@ohos.mutimedia.media' +import featureAbility from '@ohos.ability.featureAbility' + +//创建CameraManager对象 +let cameraManager +await camera.getCameraManager(globalThis.Context, (err, manager) => { + if (err) { + console.error('Failed to get the CameraManager instance ${err.message}'); + return; + } + console.log('Callback returned with the CameraManager instance'); + cameraManager = manager +}) + +//注册回调函数监听相机状态变化,获取状态变化的相机信息 +cameraManager.on('cameraStatus', (cameraStatusInfo) => { + console.log('camera : ' + cameraStatusInfo.camera.cameraId); + console.log('status: ' + cameraStatusInfo.status); +}) + +//获取相机列表 +let cameraArray +await cameraManager.getCameras((err, cameras) => { + if (err) { + console.error('Failed to get the cameras. ${err.message}'); + return; + } + console.log('Callback returned with an array of supported cameras: ' + cameras.length); + cameraArray = cameras +}) + + for(let cameraIndex = 0; cameraIndex < cameraArray.length; cameraIndex) { + console.log('cameraId : ' + cameraArray[cameraIndex].cameraId) //获取相机ID + console.log('cameraPosition : ' + cameraArray[cameraIndex].cameraPosition) //获取相机位置 + console.log('cameraType : ' + cameraArray[cameraIndex].cameraType) //获取相机类型 + console.log('connectionType : ' + cameraArray[cameraIndex].connectionType) //获取相机连接类型 + } + + //创建相机输入流 + let cameraInput + await cameraManager.createCameraInput(cameraArray[0].cameraId).then((input) => { + console.log('Promise returned with the CameraInput instance'); + cameraInput = input +}) + +//创建预览输出流 +let previewOutput +camera.createPreviewOutput((globalThis.surfaceId), (err, output) => { + if (err) { + console.error('Failed to create the PreviewOutput instance. ${err.message}'); + return; + } + console.log('Callback returned with previewOutput instance'); + previewOutput = output +}); + +//创建ImageReceiver对象,并设置照片参数 +let imageReceiver = await image.createImageReceiver(1920, 1080, 4, 8) +//获取照片显示SurfaceId +let photoSurfaceId = await imageReceiver.getReceivingSurfaceId() +//创建拍照输出流 +let photoOutput +camera.createPhotoOutput((photoSurfaceId), (err, output) => { + if (err) { + console.error('Failed to create the PhotoOutput instance. ${err.message}'); + return; + } + console.log('Callback returned with the PhotoOutput instance.'); + photoOutput = output +}); +//保存照片 +``` +照片保存方法可参考:[照片保存方法示例] + +```js +//创建视频录制的参数 +let videoProfile = { + audioBitrate : 48000, + audioChannels : 2, + audioCodec : 'audio/mp4a-latm', + audioSampleRate : 48000, + fileFormat : 'mp4', + videoBitrate : 48000, + videoCodec : 'video/mp4v-es', + videoFrameWidth : 640, + videoFrameHeight : 480, + videoFrameRate : 30 +} +let videoConfig = { + audioSourceType : 1, + videoSourceType : 0, + profile : videoProfile, + url : 'file:///data/media/01.mp4', + orientationHint : 0, + location : { latitude : 30, longitude : 130 }, +} + +//创建录像输出流 +let videoRecorder +await media.createVideoRecorder().then((recorder) => { + console.log('createVideoRecorder called') + videoRecorder = recorder +}) +//设置视频录制的参数 +await videoRecorder.prepare(videoConfig) +//获取录像SurfaceId +await videoRecorder.getInputSurface().then((id) => { + console.log('getInputSurface called') + videoSurfaceId = id +}) +``` +videoRecorder详细创建方法可参考:[视频录制开发指导](./video-recorder.md) +```js +//创建VideoOutput对象 +let videoOutput +camera.createVideoOutput((surfaceId), (err, output) => { + if (err) { + console.error('Failed to create the VideoOutput instance. ${err.message}'); + return; + } + console.log('Callback returned with the VideoOutput instance'); + videoOutput = output +}); + +``` + +#### 参数设置 + +```js +//判断设备是否支持闪光灯 +let flashStatus +await cameraInput.hasFlash().then((status) => { + console.log('Promise returned with the flash light support status:' + status); + flashStatus = status +}) +if(flashStatus) { + //判断是否支持自动闪光灯模式 + let flashModeStatus + cameraInput.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO, (err, status) => { + if (err) { + console.error('Failed to check whether the flash mode is supported. ${err.message}'); + return; + } + console.log('Callback returned with the flash mode support status: ' + status); + flashModeStatus = status + }) + if(flashModeStatus) { + //设置自动闪光灯模式 + cameraInput.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO, (err) => { + if (err) { + console.error('Failed to set the flash mode ${err.message}'); + return; + } + console.log('Callback returned with the successful execution of setFlashMode.'); + }) + } +} + +//判断是否支持连续自动变焦模式 +let focusModeStatus +cameraInput.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO, (err, status) => { + if (err) { + console.error('Failed to check whether the focus mode is supported. ${err.message}'); + return; + } + console.log('Callback returned with the focus mode support status: ' + status); + focusModeStatus = status +}) +if(focusModeStatus) { + //设置连续自动变焦模式 + cameraInput.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO, (err) => { + if (err) { + console.error('Failed to set the focus mode ${err.message}'); + return; + } + console.log('Callback returned with the successful execution of setFocusMode.'); + }) +} + +//获取相机支持的可变焦距比范围 +let zoomRatioRange +cameraInput.getZoomRatioRange((err, range) => { + if (err) { + console.error('Failed to get the zoom ratio range. ${err.message}'); + return; + } + console.log('Callback returned with zoom ratio range: ' + range.length); + zoomRatioRange = range +}) + +//设置可变焦距比 +cameraInput.setZoomRatio(zoomRatioRange[0], (err) => { + if (err) { + console.error('Failed to set the zoom ratio value ${err.message}'); + return; + } + console.log('Callback returned with the successful execution of setZoomRatio.'); +}) +``` + +#### 会话管理 + +##### 创建会话 + +```js +//创建Context对象 +let context = featureAbility.getContext() + +//创建会话 +let captureSession +await camera.createCaptureSession((context), (err, session) => { + if (err) { + console.error('Failed to create the CaptureSession instance. ${err.message}'); + return; + } + console.log('Callback returned with the CaptureSession instance.' + session); + captureSession = session +}); + +//开始配置会话 +await captureSession.beginConfig((err) => { + if (err) { + console.error('Failed to start the configuration. ${err.message}'); + return; + } + console.log('Callback invoked to indicate the begin config success.'); +}); + +//向会话中添加相机输入流 +await captureSession.addInput(cameraInput, (err) => { + if (err) { + console.error('Failed to add the CameraInput instance. ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the CameraInput instance is added.'); +}); + +//向会话中添加预览输入流 +await captureSession.addOutput(previewOutput, (err) => { + if (err) { + console.error('Failed to add the PreviewOutput instance ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the PreviewOutput instance is added.'); +}); + +//向会话中添加拍照输出流 +await captureSession.addOutput(photoOutput, (err) => { + if (err) { + console.error('Failed to add the PhotoOutput instance ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the PhotoOutput instance is added.'); +}); + +//提交会话配置 +await captureSession.commitConfig((err) => { + if (err) { + console.error('Failed to commit the configuration. ${err.message}'); + return; + } + console.log('Callback invoked to indicate the commit config success.'); +}); + +//启动会话 +await captureSession.start().then(() => { + console.log('Promise returned to indicate the session start success.'); +}) +``` + +##### 切换会话 + +```js +//停止当前会话 +await captureSession.stop((err) => { + if (err) { + console.error('Failed to stop the session ${err.message}'); + return; + } + console.log('Callback invoked to indicate the session stop success.'); +}); + +//开始配置会话 +await captureSession.beginConfig((err) => { + if (err) { + console.error('Failed to start the configuration. ${err.message}'); + return; + } + console.log('Callback invoked to indicate the begin config success.'); +}); + +//从会话中移除拍照输出流 +await captureSession.removeOutput(photoOutput, (err) => { + if (err) { + console.error('Failed to remove the PhotoOutput instance. ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the PhotoOutput instance is removed.'); +}); + +//向会话中添加录像输出流 +await captureSession.addOutput(videoOutput, (err) => { + if (err) { + console.error('Failed to add the VideoOutput instance ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the VideoOutput instance is added.'); +}); + +//提交会话配置 +await captureSession.commitConfig((err) => { + if (err) { + console.error('Failed to commit the configuration. ${err.message}'); + return; + } + console.log('Callback invoked to indicate the commit config success.'); +}); + +//启动会话 +await captureSession.start().then(() => { + console.log('Promise returned to indicate the session start success.'); +}) +``` + +#### 拍照 + +```js +let settings = { + quality: camera.QualityLevel.QUALITY_LEVEL_HIGH //设置图片质量高 + rotation: camera.ImageRotation.ROTATION_0, //设置图片旋转角度0 +} +//使用当前拍照设置进行拍照 +photoOutput.capture(settings, (err) => { + if (err) { + console.error('Failed to capture the photo ${err.message}'); + return; + } + console.log('Callback invoked to indicate the photo capture request success.'); +}); +``` + +#### 录像 + +```js +//启动录像输出流 +videoOutput.start((err) => { + if (err) { + console.error('Failed to start the video output ${err.message}'); + return; + } + console.log('Callback invoked to indicate the video output start success.'); +}); + +//开始录像 +await videoRecorder.start().then(() => { + console.info('videoRecorder start success'); +} + +//停止录像 +await videoRecorder.stop().then(() => { + console.info('stop success'); +} + +//停止录像输出流 +await videoOutput.stop((err) => { + if (err) { + console.error('Failed to stop the video output ${err.message}'); + return; + } + console.log('Callback invoked to indicate the video output stop success.'); +}); +``` + +#### 释放资源 + +```js +//停止当前会话 +await captureSession.stop((err) => { + if (err) { + console.error('Failed to stop the session ${err.message}'); + return; + } + console.log('Callback invoked to indicate the session stop success.'); +}); +//释放会话(自动释放输入流与输出流) +await captureSession.release((err) => { + if (err) { + console.error('Failed to release the CaptureSession instance ${err.message}'); + return; + } + console.log('Callback invoked to indicate that the CaptureSession instance is released successfully.'); +}); +``` \ No newline at end of file