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 '@kit.CameraKit'; 26 import { image } from '@kit.ImageKit'; 27 import { BusinessError } from '@kit.BasicServicesKit'; 28 import { photoAccessHelper } from '@kit.MediaLibraryKit'; 29 ``` 30 312. 确定拍照输出流。 32 33 通过[CameraOutputCapability](../../reference/apis-camera-kit/js-apis-camera.md#cameraoutputcapability)类中的photoProfiles属性,可获取当前设备支持的拍照输出流,通过[createPhotoOutput](../../reference/apis-camera-kit/js-apis-camera.md#createphotooutput11)方法创建拍照输出流。 34 35 ```ts 36 function getPhotoOutput(cameraManager: camera.CameraManager, 37 cameraOutputCapability: camera.CameraOutputCapability): camera.PhotoOutput | undefined { 38 let photoProfilesArray: Array<camera.Profile> = cameraOutputCapability.photoProfiles; 39 if (!photoProfilesArray) { 40 console.error("createOutput photoProfilesArray == null || undefined"); 41 } 42 let photoOutput: camera.PhotoOutput | undefined = undefined; 43 try { 44 photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]); 45 } catch (error) { 46 let err = error as BusinessError; 47 console.error(`Failed to createPhotoOutput. error: ${JSON.stringify(err)}`); 48 } 49 return photoOutput; 50 } 51 ``` 52 533. 查询当前设备当前模式是否支持相应分段式能力。 54 55 ```ts 56 function isDeferredImageDeliverySupported(photoOutput: camera.PhotoOutput): boolean { 57 let isSupported: boolean = false; 58 if (photoOutput !== null) { 59 isSupported = photoOutput.isDeferredImageDeliverySupported(camera.DeferredDeliveryImageType.PHOTO); 60 } 61 console.info(`isDeferredImageDeliverySupported isSupported: ${isSupported}`); 62 return isSupported; 63 } 64 ``` 65 664. 使能分段式拍照能力。 67 68 ```ts 69 function EnableDeferredPhotoAbility(photoOutput: camera.PhotoOutput): void { 70 photoOutput.deferImageDelivery(camera.DeferredDeliveryImageType.PHOTO); 71 } 72 ``` 73 745. 查询是否已经成功使能分段式拍照。 75 76 ```ts 77 function isDeferredImageDeliveryEnabled(photoOutput: camera.PhotoOutput): boolean { 78 let isEnabled: boolean = false; 79 if (photoOutput !== null) { 80 isEnabled = photoOutput.isDeferredImageDeliveryEnabled(camera.DeferredDeliveryImageType.PHOTO); 81 } 82 console.info(`isDeferredImageDeliveryEnabled isEnabled: ${isEnabled}`); 83 return isEnabled; 84 } 85 ``` 86 876. 触发拍照,与普通拍照方式相同,请参考[拍照](camera-shooting.md)。 88 89 90 91## 状态监听 92 931. 注册缩略图监听回调。 94 95 ```ts 96 function onPhotoOutputDeferredPhotoProxyAvailable(photoOutput: camera.PhotoOutput): void { 97 photoOutput.on('deferredPhotoProxyAvailable', (err: BusinessError, proxyObj: camera.DeferredPhotoProxy): void => { 98 if (err) { 99 console.info(`deferredPhotoProxyAvailable error: ${JSON.stringify(err)}.`); 100 return; 101 } 102 console.info('photoOutPutCallBack deferredPhotoProxyAvailable'); 103 // 获取缩略图 pixelMap 104 proxyObj.getThumbnail().then((thumbnail: image.PixelMap) => { 105 AppStorage.setOrCreate('proxyThumbnail', thumbnail); 106 }); 107 // 调用媒体库接口落盘缩略图,详细实现见2。 108 saveDeferredPhoto(proxyObj); 109 }); 110 } 111 ``` 112 113 114 1152. 调用媒体库接口落盘缩略图。 116 117 Context获取方式请参考:[获取UIAbility的上下文信息](../../application-models/uiability-usage.md#获取uiability的上下文信息)。 118 119 ```ts 120 let context = getContext(this); 121 122 async function saveDeferredPhoto(proxyObj: camera.DeferredPhotoProxy) { 123 try { 124 // 创建 photoAsset 125 let accessHelper = photoAccessHelper.getPhotoAccessHelper(context); 126 let testFileName = 'testFile' + Date.now() + '.jpg'; 127 let photoAsset = await accessHelper.createAsset(testFileName); 128 // 将缩略图代理类传递给媒体库 129 let mediaRequest: photoAccessHelper.MediaAssetChangeRequest = new photoAccessHelper.MediaAssetChangeRequest(photoAsset); 130 mediaRequest.addResource(photoAccessHelper.ResourceType.PHOTO_PROXY, proxyObj); 131 let res = await accessHelper.applyChanges(mediaRequest); 132 console.info('saveDeferredPhoto success.'); 133 } catch (err) { 134 console.error(`Failed to saveDeferredPhoto. error: ${JSON.stringify(err)}`); 135 } 136 } 137 ``` 138