diff --git a/zh-cn/application-dev/media/Readme-CN.md b/zh-cn/application-dev/media/Readme-CN.md index d177b1890ec9172e129c9034c15ae62658a18414..9050ccfd492d294e9537283f0b8bf5c5ec955704 100755 --- a/zh-cn/application-dev/media/Readme-CN.md +++ b/zh-cn/application-dev/media/Readme-CN.md @@ -62,6 +62,7 @@ - 相机最佳实践 - [拍照实现方案](camera-shooting-case.md) - [录像实现方案](camera-recording-case.md) + - [人像模式拍照实现方案](camera-mode.md) - [性能提升方案(仅对系统应用开放)](camera-performance-improvement.md) - 图片 - [图片开发概述](image-overview.md) diff --git a/zh-cn/application-dev/media/camera-mode.md b/zh-cn/application-dev/media/camera-mode.md new file mode 100644 index 0000000000000000000000000000000000000000..5bd22a536e87e5f9976508407bb17cb51d22153e --- /dev/null +++ b/zh-cn/application-dev/media/camera-mode.md @@ -0,0 +1,258 @@ +# 人像模式拍照实现方案 + +## 开发流程 + +人像模式依赖于模式化管理器,在获取到模式化管理的能力后,开始创建拍照流 + +模式化管理是对于cameraManager功能的增强与扩充,主要用于一些高级功能的管理,开发流程如下 + +![portraitgraphing Development Process](figures/portrait-capture-development-process.png) + +## 完整示例 + +```ts +import camera from '@ohos.multimedia.camera' +import image from '@ohos.multimedia.image' +import media from '@ohos.multimedia.media' + + +// 创建CameraManager对象 +context: any = getContext(this) +let cameraManager = camera.getCameraManager(this.context) +if (!cameraManager) { + console.error("camera.getCameraManager error") + return; +} +// 创建ModeManager对象 +context: any = getContext(this) +let modeManager = camera.getModeManager(this.context) +if (!cameraManager) { + console.error("camera.getModeManager error") + return; +} +// 监听相机状态变化 +cameraManager.on('cameraStatus', (err, cameraStatusInfo) => { + console.info(`camera : ${cameraStatusInfo.camera.cameraId}`); + console.info(`status: ${cameraStatusInfo.status}`); +}) +// 获取相机列表 +let cameraArray = cameraManager.getSupportedCameras(); +if (cameraArray.length <= 0) { + console.error("cameraManager.getSupportedCameras error") + return; +} + +for (let index = 0; index < cameraArray.length; index++) { + console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID + console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置 + console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型 + console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型 +} + +// 获取模式列表 +let cameraModeArray = modeManager.getSupportedModes(cameraArray[0]); +if (cameraModeArray.length <= 0) { + console.error("modeManager.getSupportedModes error") + return; +} +// 创建相机输入流 +let cameraInput +try { + cameraInput = cameraManager.createCameraInput(cameraArray[0]); +} catch (error) { + console.error('Failed to createCameraInput errorCode = ' + error.code); +} +// 监听cameraInput错误信息 +let cameraDevice = cameraArray[0]; +cameraInput.on('error', cameraDevice, (error) => { + console.info(`Camera input error code: ${error.code}`); +}) + +// 打开相机 +await cameraInput.open(); + +// 获取当前模式相机设备支持的输出流能力 +let cameraOutputCap = modeManager.getSupportedOutputCapability(cameraArray[0], cameraModeArray[0]); +if (!cameraOutputCap) { + console.error("modeManager.getSupportedOutputCapability error") + return; +} +console.info("outputCapability: " + JSON.stringify(cameraOutputCap)); + +let previewProfilesArray = cameraOutputCap.previewProfiles; +if (!previewProfilesArray) { + console.error("createOutput previewProfilesArray == null || undefined") +} + +let photoProfilesArray = cameraOutputCap.photoProfiles; +if (!photoProfilesArray) { + console.error("createOutput photoProfilesArray == null || undefined") +} + +// 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface +let previewOutput +try { + previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId) +} catch (error) { + console.error("Failed to create the PreviewOutput instance.") +} +// 监听预览输出错误信息 +previewOutput.on('error', (error) => { + console.info(`Preview output error code: ${error.code}`); +}) +// 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置 +let imageReceiver = await image.createImageReceiver(1920, 1080, 4, 8) +// 获取照片显示SurfaceId +let photoSurfaceId = await imageReceiver.getReceivingSurfaceId() +// 创建拍照输出流 +let photoOutput +try { + photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId) +} catch (error) { + console.error('Failed to createPhotoOutput errorCode = ' + error.code); +} +//创建portrait会话 +let portraitSession +try { + portraitSession = modeManager.createCaptureSession(cameraModeArray[0]) +} catch (error) { + console.error('Failed to create the CaptureSession instance. errorCode = ' + error.code); +} + +// 监听portraitSession错误信息 +portraitSession.on('error', (error) => { + console.info(`Capture session error code: ${error.code}`); +}) + +// 开始配置会话 +try { + portraitSession.beginConfig() +} catch (error) { + console.error('Failed to beginConfig. errorCode = ' + error.code); +} + +// 向会话中添加相机输入流 +try { + portraitSession.addInput(cameraInput) +} catch (error) { + console.error('Failed to addInput. errorCode = ' + error.code); +} + +// 向会话中添加预览输出流 +try { + portraitSession.addOutput(previewOutput) +} catch (error) { + console.error('Failed to addOutput(previewOutput). errorCode = ' + error.code); +} + +// 向会话中添加拍照输出流 +try { + portraitSession.addOutput(photoOutput) +} catch (error) { + console.error('Failed to addOutput(photoOutput). errorCode = ' + error.code); +} + +// 提交会话配置 +await portraitSession.commitConfig() + +// 启动会话 +await portraitSession.start().then(() => { + console.info('Promise returned to indicate the session start success.'); +}) + +// 获取支持的美颜类型 +let beautyTypes +try { + beautyTypes = portraitSession.getSupportedBeautyTypes() +} catch (error) { + console.error('Failed to get the beauty types. errorCode = ' + error.code); +} +// 获取支持的美颜类型对应的美颜强度范围 +let beautyRanges +try { + beautyRanges = portraitSession.getSupportedBeautyRanges(beautyTypes[0]) +} catch (error) { + console.error('Failed to get the beauty types ranges. errorCode = ' + error.code); +} +// 设置美颜类型及对应的美颜强度 +try { + portraitSession.setBeauty(beautyTypes[0], beautyRanges[0]) +} catch (error) { + console.error('Failed to set the beauty type value. errorCode = ' + error.code); +} +// 获取已经设置的美颜类型对应的美颜强度 +let beautyLevel +try { + beautyLevel = portraitSession.getBeauty(beautyTypes[0]) +} catch (error) { + console.error('Failed to get the beauty type value. errorCode = ' + error.code); +} + +// 获取支持的滤镜类型 +let filterTypes +try { + filterTypes = portraitSession.getSupportedFilters() +} catch (error) { + console.error('Failed to get the filter types. errorCode = ' + error.code); +} +// 设置滤镜类型 +try { + portraitSession.setFilter(filterTypes[0]) +} catch (error) { + console.error('Failed to set the filter type value. errorCode = ' + error.code); +} +// 获取已经设置的滤镜类型 +let filter +try { + filter = portraitSession.getFilter() +} catch (error) { + console.error('Failed to get the filter type value. errorCode = ' + error.code); +} + +// 获取支持的虚化类型 +let portraitTypes +try { + portraitTypes = portraitSession.getSupportedPortraitEffects() +} catch (error) { + console.error('Failed to get the portrait effects types. errorCode = ' + error.code); +} +// 设置虚化类型 +try { + portraitSession.setPortraitEffect(portraitTypes[0]) +} catch (error) { + console.error('Failed to set the portrait effects value. errorCode = ' + error.code); +} +// 获取已经设置的虚化类型 +let effect +try { + effect = portraitSession.getPortraitEffect() +} catch (error) { + console.error('Failed to get the portrait effects value. errorCode = ' + error.code); +} + +// 使用当前拍照设置进行拍照 +photoOutput.capture(settings, async (err) => { + if (err) { + console.error('Failed to capture the photo ${err.message}'); + return; + } + console.info('Callback invoked to indicate the photo capture request success.'); +}); +// 停止当前会话 +portraitSession.stop() + +// 释放相机输入流 +cameraInput.close() + +// 释放预览输出流 +previewOutput.release() + +// 释放拍照输出流 +photoOutput.release() + +// 释放会话 +portraitSession.release() + +// 会话置空 +portraitSession = null +``` diff --git a/zh-cn/application-dev/media/figures/portrait-capture-development-process.png b/zh-cn/application-dev/media/figures/portrait-capture-development-process.png new file mode 100644 index 0000000000000000000000000000000000000000..bf9ff3806ac78ba47e6a3855e82730a97213dc28 Binary files /dev/null and b/zh-cn/application-dev/media/figures/portrait-capture-development-process.png differ diff --git a/zh-cn/application-dev/reference/apis/js-apis-camera.md b/zh-cn/application-dev/reference/apis/js-apis-camera.md index ee5683cb1023c6722f70d68f3f147a9616c9d721..bc142a89e0bc30656e500e536e519716e6778ee3 100644 --- a/zh-cn/application-dev/reference/apis/js-apis-camera.md +++ b/zh-cn/application-dev/reference/apis/js-apis-camera.md @@ -44,6 +44,44 @@ getCameraManager(context: Context): CameraManager ```js let cameraManager = camera.getCameraManager(context); ``` +## camera.getModeManager + +getModeManager(context: Context): ModeManager + +获取模式化管理器实例,同步返回结果。 + +模式化管理是对于cameraManager功能的增强与扩充,主要用于一些高级功能的管理(如人像模式)。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------------------------- | ---- | ---------------------------- | +| context | [Context](js-apis-inner-app-context.md) | 是 | 应用上下文。 | + +**返回值:** + +| 类型 | 说明 | +| --------------------------------------| -----------| +| [ModeManager](#modemanager) | 模式化管理器。| + +**错误码:** + +以下错误码的详细介绍请参见[Camera错误码](../errorcodes/errorcode-camera.md) + +| 错误码ID | 错误信息 | +| --------------- | --------------- | +| 7400101 | Parameter missing or parameter type incorrect | +| 7400201 | Camera service fatal error. | + +**示例:** + +```js +let modeManager = camera.getModeManager(context); +``` ## CameraStatus @@ -122,6 +160,65 @@ let cameraManager = camera.getCameraManager(context); | DEVICE_PREEMPTED | 7400109 | 相机被抢占导致无法使用 | | SERVICE_FATAL_ERROR | 7400201 | 相机服务错误返回。 | +## CameraMode + +相机模式。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +| 名称 | 值 | 说明 | +| ----------------| ---- | ---------| +| NORMAL | 0 | 普通模式 | +| CAPTURE | 1 | 拍照模式 | +| VIDEO | 2 | 录像模式 | +| PORTRAIT | 3 | 人像模式 | +| NIGHT | 4 | 夜景模式 | +| PROFESSIONAL | 5 | 专业模式 | +| SLOW_MOTION | 6 | 慢动作模式| + +## FilterType + +滤镜类型。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +| 名称 | 值 | 说明 | +| ----------------| ---- | ---------| +| NONE | 0 | 原图 | +| CLASSIC | 1 | 经典 | +| DAWN | 2 | 晨光 | +| PURE | 3 | 清纯 | +| GREY | 4 | 灰调 | +| NATURAL | 5 | 自然 | +| MORI | 6 | 森系 | +| FAIR | 7 | 白皙 | +| PINK | 8 | 粉调 | + + +## PortraitEffect + +人像效果类型。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +| 名称 | 值 | 说明 | +| ----------------| ---- | ---------| +| OFF | 0 | 关闭 | +| CIRCLES | 1 | 圆形 | + +## BeautyType + +美颜类型。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +| 名称 | 值 | 说明 | +| ----------------| ---- | ---------| +| AUTO_TYPE | 0 | 自动 | +| SKIN_SMOOTH | 1 | 光滑 | +| FACE_SLENDER | 2 | 瘦脸 | +| SKIN_TONE | 3 | 肤色 | + ## CameraManager 相机管理器类,使用前需要通过getCameraManager获取相机管理实例。 @@ -720,6 +817,104 @@ function getDeferredPreviewOutput(context: Context, previewProfile: camera.Profi const output: Promise = cameraManager.createDeferredPreviewOutput(previewProfile); return output; } +``` +## ModeManager + +相机模式化管理器类,使用前需要通过[getModeManager](#cameragetmodemanager)获取相机模式化管理实例。 + +### getSupportedModes + +getSupportedModes(camera: CameraDevice): Array\ + +获取指定相机设备支持的模式列表,同步返回结果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | -------------------------- | ---- | ------------------- | +| camera | \<[CameraDevice](#cameradevice)> | 是 | 相机设备实例,通过[getSupportedCameras](#getsupportedcameras)接口获取。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Array\<[CameraMode](#cameramode)> | 支持的模式列表。 | + +**示例:** + +```js +let cameraModes = cameraManager.getSupportedModes(cameraDevices[0]); + +``` + +### getSupportedOutputCapability + +getSupportedOutputCapability(camera:CameraDevice, mode: CameraMode): CameraOutputCapability + +获取指定模式下相机设备支持的输出能力,同步返回结果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------ |--------------------------------------------------------------- | -- | -------------------------- | +| cameraDevice | [CameraDevice](#cameradevice) | 是 | 相机设备,通过[getSupportedCameras](#getsupportedcameras)接口获取。 | +| mode | [CameraMode](#cameramode) | 是 | 指定模式,通过[getSupportedModes](#getsupportedmodes)接口获取。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| [CameraOutputCapability](#cameraoutputcapability) | 相机输出能力。 | + +**示例:** + +```js +let cameras = cameraManager.getSupportedCameras(); +let cameraDevice = cameras[0]; +let cameraModes = modeManager.getSupportedModes(cameraDevice); +let mode = cameraModes[0] +let cameraOutputCapability = modeManager.getSupportedOutputCapability(cameraDevice, mode); + +``` +### createCaptureSession + +createCaptureSession(mode: CameraMode): CaptureSession + +根据当前的模式名,创建指定模式的会话。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------ |--------------------------------------------------------------- | -- | -------------------------- | +| mode | [CameraMode](#cameramode) | 是 | 指定模式,通过[getSupportedModes](#getsupportedmodes)获取。 | + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| [CaptureSession](#capturesession) | 指定模式的会话实例。 | + +**示例:** + +```js +let cameras = cameraManager.getSupportedCameras(); +let cameraDevice = cameras[0]; +let cameraModes = modeManager.getSupportedModes(cameraDevice); +let mode = cameraModes[0] +let captureSession = modeManager.createCaptureSession(mode); + ``` ## PrelaunchConfig @@ -2418,6 +2613,187 @@ try { console.log(error.code); } ``` +### getSupportedFilters + +getSupportedFilters(): Array\ + +获取当前支持的滤镜效果列表。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**返回值:** + +| 类型 | 说明 | +| ---------- | ----------------------------- | +| Array\ | 返回支持的滤镜效果列表。 | + +**示例:** + +```js +let FilterTypes = captureSession.getSupportedFilters(); +``` +### setFilter + +setFilter(filter: FilterType): void + +设置滤镜效果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ----------------------------| ---- | ---------------------| +| filter | [FilterType](#filtertype) | 是 | 当前用户设置的滤镜类型。 | + +**示例:** + +```js +let FilterTypes = captureSession.getSupportedFilters(); +if (!FilterTypes.empty()) { + captureSession.setFilter(FilterTypes[0]); +} +``` + +### getFilter + + getFilter(): number + +获取当前已设置的滤镜效果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**返回值:** + +| 类型 | 说明 | +| ---------- | ----------------------------| +| [FilterType](#filtertype)| 已设置的滤镜效果。可查阅[FilterType](#filtertype)。| + +**示例:** + +```js +let FilterType = captureSession.getFilter(); +``` +### getSupportedBeautyTypes + +getSupportedBeautyTypes(): Array + +获取当前支持的美颜效果列表。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**返回值:** + +| 类型 | 说明 | +| ---------- | ----------------------------- | +| Array\| 返回当前支持的美颜效果列表。 | + +**示例:** + +```js +let FilterTypes = captureSession.getSupportedBeautyTypes(); +``` +### getSupportedBeautyRanges + +getSupportedBeautyRanges(type: BeautyType): Array + +获取指定美颜效果的范围值。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------| ---- | ----------| +| type | [BeautyType](#beautytype) | 是 | 美颜类型。 | + +**返回值:** + +| 类型 | 说明 | +| ---------- | ----------------------------- | +| Array\ | 当前美颜类型所支持的美颜强度。 | + +**示例:** + +```js +let beautyTypes = captureSession.getSupportedBeautyTypes(); +if (!beautyTypes.empty()) { + let nums = captureSession.getSupportedBeautyRanges(beautyTypes[0]); +} +``` + +### setBeauty + +setBeauty(type: BeautyType, value: number): void + +设置美颜类型以及对应的美颜强度 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | --------------------------| ---- | --------------------- | +| type | [BeautyType](#beautytype) | 是 | 美颜类型 | +| value | [number] | 是 | 美颜强度,通过[getSupportedBeautyRanges](#getsupportedbeautyranges)接口获取。| + +**示例:** + +```js +let beautyTypes = captureSession.getSupportedBeautyTypes(); +let beautyLevels; +if (!beautyTypes.empty()) { + beautyLevels = captureSession.getSupportedBeautyRanges(beautyTypes[0]); +} +if (!beautyTypes.empty() && beautyLevels.empty()) { + captureSession.setBeauty(beautyTypes[0], beautyLevels[0]); +} +``` + +### getBeauty + +getBeauty(type: BeautyType): number + +查询当前已设置的美颜效果对应的美颜强度。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------- | ---- | --------------------- | +| type | [BeautyType](#beautytype) | 是 | 美颜类型 | + +**返回值:** +| 参数名 | 类型 | 必填 | 说明 | +| -------- | ------------------------------------------------- | ---- | --------------------- | +| value | [number] | 是 | 美颜强度 | + +**示例:** + +```js +let BeautyTypes = captureSession.getSupportedBeautyTypes(); +let beautyLevels; +if (!BeautyTypes.empty()) { + beautyLevels = captureSession.getSupportedBeautyRanges(BeautyTypes[0]); +} +if (!BeautyTypes.empty() && beautyLevels.empty()) { + captureSession.setBeauty(BeautyTypes[0], beautyLevels[0]); +} +let beautyLevel = captureSession.getBeauty(BeautyTypes[0]); +``` ### on('focusStateChange') @@ -2464,6 +2840,80 @@ captureSession.on('error', (error) => { console.log(`Capture session error code: ${error.code}`); }) ``` +## PortraitSession + +继承自[CaptureSession](#capturesession),用于设置人像模式的参数。 + +### getSupportedPortraitEffects + +getSupportedPortraitEffects(): Array + +获取支持的人像虚化效果列表。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| Array<[PortraitEffect](#portraiteffect) > | 支持的人像虚化效果列表。 | + +**示例:** + +```js +let portraitEffect = PortraitSession.getSupportedPortraitEffects(); +``` +### setPortraitEffect + +setPortraitEffect(effect: PortraitEffect): void + +设置人像虚化效果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**参数:** + +| 参数名 | 类型 | 必填 | 说明 | +| ------------ |--------------------------------------------------------------- | -- | -------------------------- | +| effect | [PortraitEffect](#portraiteffect) | 是 | 人像虚化效果,通过[getSupportedPortraitEffects](#getsupportedportraiteffects)接口获取。 | + +**示例:** + +```js +let portraitEffects = PortraitSession.getSupportedPortraitEffects(); +if (!portraitEffects.empty()) { + PortraitSession.setPortraitEffect(portraitEffects[0]); +} +``` +### getPortraitEffect + +getPortraitEffect(): PortraitEffect + +获取当前设置的人像虚化效果。 + +**系统接口:** 此接口为系统接口。 + +**系统能力:** SystemCapability.Multimedia.Camera.Core + +**返回值:** + +| 类型 | 说明 | +| ----------------------------------------------- | ---------------------------- | +| [PortraitEffect](#portraiteffect) | 当前设置的人像虚化效果。 | + + +**示例:** + +```js +let portraitEffects = PortraitSession.getSupportedPortraitEffects(); +if (!portraitEffects.empty()) { + PortraitSession.setPortraitEffect(portraitEffects[0]); +} +``` ## CameraOutput diff --git a/zh-cn/application-dev/website.md b/zh-cn/application-dev/website.md index 344729e95be28d4097bb9151ac5c90ae40e89494..0e281e1ffca35d4ac162465c452ae502d76e094d 100644 --- a/zh-cn/application-dev/website.md +++ b/zh-cn/application-dev/website.md @@ -511,6 +511,7 @@ - 相机最佳实践 - [拍照实现方案](media/camera-shooting-case.md) - [录像实现方案](media/camera-recording-case.md) + - [人像模式拍照实现方案](media/camera-mode.md) - [性能提升方案(仅对系统应用开放)](media/camera-performance-improvement.md) - 图片 - [图片开发概述](media/image-overview.md)