• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 高性能拍照(仅对系统应用开放)(ArkTS)
2
3高性能拍照是相机的重要功能之一,优化了拍照响应时延,提升用户体验。高性能拍照又名分段式拍照,应用下发拍照请求后,**第一阶段**系统会很快返回给应用一张**缩略图**,应用需将该图片及相关信息存入媒体库;**第二阶段**子服务会根据系统压力及定制化场景进行调度,将后处理好的**原图**回传给媒体库。
4
5应用开发分段式拍照主要分为以下步骤:
6
7- 查询当前设备的当前模式是否支持分段式拍照。
8- 如果支持分段式能力,可以调用相机框架提供的使能接口**使能**分段式能力。
9- 监听缩略图回调,获取缩略图代理类,将缩略图存入媒体库。
10
11> **说明:**
12>
13> - 分段式拍照能力是根据**设备**和**模式**决定的,不同的设备支持不同的模式,不同的模式下分段式能力也各有不同,所以应用在切换设备或模式后需要重新使能分段式能力。
14> - 分段式使能需要在配流期间完成,配流完成后的使能操作不生效。
15
16
17
18## 开发步骤
19
20详细的API说明请参考[Camera API参考](../../reference/apis-camera-kit/js-apis-camera.md)。
21
221. 导入依赖,需要导入相机框架、媒体库、图片相关领域依赖。
23
24   ```ts
25   import camera from '@ohos.multimedia.camera';
26   import image from '@ohos.multimedia.image';
27   import mediaLibrary from '@ohos.multimedia.mediaLibrary';
28   import fs from '@ohos.file.fs';
29   import photoAccessHelper from '@ohos.file.photoAccessHelper';
30   import { BusinessError } from '@ohos.base';
31   ```
32
332. 确定拍照输出流。
34
35   通过[CameraOutputCapability](../../reference/apis-camera-kit/js-apis-camera.md#cameraoutputcapability)类中的photoProfiles属性,可获取当前设备支持的拍照输出流,通过[createPhotoOutput](../../reference/apis-camera-kit/js-apis-camera.md#createphotooutput11)方法创建拍照输出流。
36
37   ```ts
38   function getPhotoOutput(cameraManager: camera.CameraManager,
39                           cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined {
40     let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles;
41     if (!photoProfilesArray) {
42       console.error("createOutput photoProfilesArray == null || undefined");
43     }
44     let photoOutput: camera.PhotoOutput | undefined = undefined;
45     try {
46       photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
47     } catch (error) {
48       let err = error as BusinessError;
49       console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`);
50     }
51     return photoOutput;
52   }
53   ```
54
553. 查询当前设备当前模式是否支持相应分段式能力。
56
57   ```ts
58   function isDeferredImageDeliverySupported(photoOutput: camera.PhotoOutput): boolean {
59     let isSupported: boolean = false;
60     if (photoOutput !== null) {
61       isSupported = photoOutput.isDeferredImageDeliverySupported(camera.DeferredDeliveryImageType.PHOTO);
62     }
63     console.info(`isDeferredImageDeliverySupported isSupported: ${isSupported}`);
64     return isSupported;
65   }
66   ```
67
684. 使能分段式拍照能力。
69
70   ```ts
71   function EnableDeferredPhotoAbility(photoOutput: camera.PhotoOutput): void {
72     photoOutput.deferImageDelivery(camera.DeferredDeliveryImageType.PHOTO);
73   }
74   ```
75
765. 查询是否已经成功使能分段式拍照。
77
78   ```ts
79   function isDeferredImageDeliveryEnabled(photoOutput: camera.PhotoOutput): boolean {
80   	 let isEnabled: boolean = false;
81     if (photoOutput !== null) {
82   	   isEnabled = photoOutput.isDeferredImageDeliveryEnabled(camera.DeferredDeliveryImageType.PHOTO);
83     }
84     console.info(`isDeferredImageDeliveryEnabled isEnabled: ${isEnabled}`);
85     return isEnabled;
86   }
87   ```
88
896. 触发拍照,与普通拍照方式相同,请参考[拍照](camera-shooting.md)。
90
91
92
93## 状态监听
94
951. 注册缩略图监听回调。
96
97   ```ts
98   function onPhotoOutputDeferredPhotoProxyAvailable(photoOutput: camera.PhotoOutput): void {
99     photoOutput.on('deferredPhotoProxyAvailable', (err: BusinessError, proxyObj: camera.DeferredPhotoProxy): void => {
100       if (err) {
101         console.info(`deferredPhotoProxyAvailable error: ${JSON.stringify(err)}.`);
102         return;
103       }
104       console.info('photoOutPutCallBack deferredPhotoProxyAvailable');
105       // 获取缩略图 pixelMap
106       proxyObj.getThumbnail().then((thumbnail: image.PixelMap) => {
107         AppStorage.setOrCreate('proxyThumbnail', thumbnail);
108       });
109       // 调用媒体库接口落盘缩略图,详细实现见2。
110       saveDeferredPhoto(proxyObj);
111     });
112   }
113   ```
114
115
116
1172. 调用媒体库接口落盘缩略图。
118
119   Context获取方式请参考:[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息)。
120
121   ```ts
122   let context = getContext(this);
123
124   async function saveDeferredPhoto(proxyObj: camera.DeferredPhotoProxy) {
125     try {
126       // 创建 photoAsset
127       let photoAccessHelper = PhotoAccessHelper.getPhotoAccessHelper(context);
128       let testFileName = 'testFile' + Date.now() + '.jpg';
129       let photoAsset = await photoAccessHelper.createAsset(testFileName);
130       // 将缩略图代理类传递给媒体库
131       let mediaRequest: PhotoAccessHelper.MediaAssetChangeRequest = new PhotoAccessHelper.MediaAssetChangeRequest(photoAsset);
132       mediaRequest.addResource(PhotoAccessHelper.ResourceType.PHOTO_PROXY, proxyObj);
133       let res = await photoAccessHelper.applyChanges(mediaRequest);
134       console.info('saveDeferredPhoto success.');
135     } catch (err) {
136       console.error(`Failed to saveDeferredPhoto. error: ${JSON.stringify(err)}`);
137     }
138   }
139   ```
140