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