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