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