• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# High-Performance Camera Photographing Sample (for System Applications Only) (ArkTS)
2
3This topic provides sample code that covers the complete high-performance photographing process to help you understand the complete API calling sequence.
4
5Before referring to the sample code, you are advised to read [High-Performance Camera Photographing (for System Applications Only) (ArkTS)] (camera-deferred-photo.md), [Device Input Management](camera-device-input.md), [Camera Session Management](camera-session-management.md), and [Camera Photographing](camera-shooting.md).
6
7## Development Process
8
9After obtaining the output stream capabilities supported by the camera, create a photo stream. The development process is as follows:
10
11![deferred-photo-development-process](figures/deferred-photo-development-process.png)
12
13## Sample Code
14
15For details about how to obtain the context, see [Obtaining the Context of UIAbility](../application-models/uiability-usage.md#obtaining-the-context-of-uiability).
16
17```ts
18import camera from '@ohos.multimedia.camera';
19import image from '@ohos.multimedia.image';
20import { BusinessError } from '@ohos.base';
21import common from '@ohos.app.ability.common';
22import fs from '@ohos.file.fs';
23import PhotoAccessHelper from '@ohos.file.photoAccessHelper';
24
25let context = getContext(this);
26
27// Flush the original image in write-file mode.
28async function savePicture(photoObj: camera.Photo): Promise<void> {
29  let photoAccessHelper = PhotoAccessHelper.getPhotoAccessHelper(context);
30  let testFileName = 'testFile' + Date.now() + '.jpg';
31  // To call createAsset(), the application must have the ohos.permission.READ_IMAGEVIDEO and ohos.permission.WRITE_IMAGEVIDEO permissions.
32  let photoAsset = await photoAccessHelper.createAsset(testFileName);
33  const fd = await photoAsset.open('rw');
34  let buffer: ArrayBuffer | undefined = undefined;
35  photoObj.main.getComponent(image.ComponentType.JPEG, (errCode: BusinessError, component: image.Component): void => {
36    if (errCode || component === undefined) {
37      console.error('getComponent failed');
38      return;
39    }
40    if (component.byteBuffer) {
41      buffer = component.byteBuffer;
42    } else {
43      console.error('byteBuffer is null');
44      return;
45    }
46  });
47  if (buffer) {
48    await fs.write(fd, buffer);
49  }
50  await photoAsset.close(fd);
51  await photoObj.release();
52}
53
54// Flush the thumbnail by calling the mediaLibrary API.
55async function saveDeferredPhoto(proxyObj: camera.DeferredPhotoProxy): Promise<void> {
56  try {
57    // Create a photoAsset.
58    let photoAccessHelper = PhotoAccessHelper.getPhotoAccessHelper(context);
59    let testFileName = 'testFile' + Date.now() + '.jpg';
60    let photoAsset = await photoAccessHelper.createAsset(testFileName);
61    // Pass the thumbnail proxy class object to the mediaLibrary.
62    let mediaRequest: PhotoAccessHelper.MediaAssetChangeRequest = new PhotoAccessHelper.MediaAssetChangeRequest(photoAsset);
63    mediaRequest.addResource(PhotoAccessHelper.ResourceType.PHOTO_PROXY, proxyObj);
64    let res = await photoAccessHelper.applyChanges(mediaRequest);
65    console.info('saveDeferredPhoto success.');
66  } catch (err) {
67    console.error(`Failed to saveDeferredPhoto. error: ${JSON.stringify(err)}`);
68  }
69}
70
71async function deferredPhotoCase(baseContext: common.BaseContext, surfaceId: string): Promise<void> {
72  // Create a CameraManager object.
73  let cameraManager: camera.CameraManager = camera.getCameraManager(baseContext);
74  if (!cameraManager) {
75    console.error("camera.getCameraManager error");
76    return;
77  }
78  // Listen for camera status changes.
79  cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => {
80    console.info(`camera : ${cameraStatusInfo.camera.cameraId}`);
81    console.info(`status: ${cameraStatusInfo.status}`);
82  });
83
84  // Obtain the camera list.
85  let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
86  if (cameraArray.length <= 0) {
87    console.error("cameraManager.getSupportedCameras error");
88    return;
89  }
90
91  for (let index = 0; index < cameraArray.length; index++) {
92    console.info('cameraId : ' + cameraArray[index].cameraId);                          // Obtain the camera ID.
93    console.info('cameraPosition : ' + cameraArray[index].cameraPosition);              // Obtain the camera position.
94    console.info('cameraType : ' + cameraArray[index].cameraType);                      // Obtain the camera type.
95    console.info('connectionType : ' + cameraArray[index].connectionType);              // Obtain the camera connection type.
96  }
97
98  // Create a camera input stream.
99  let cameraInput: camera.CameraInput | undefined = undefined;
100  try {
101    cameraInput = cameraManager.createCameraInput(cameraArray[0]);
102  } catch (error) {
103    let err = error as BusinessError;
104    console.error('Failed to createCameraInput errorCode = ' + err.code);
105  }
106  if (cameraInput === undefined) {
107    return;
108  }
109
110  // Listen for camera input errors.
111  let cameraDevice: camera.CameraDevice = cameraArray[0];
112  cameraInput.on('error', cameraDevice, (error: BusinessError) => {
113    console.error(`Camera input error code: ${error.code}`);
114  })
115
116  // Open a camera.
117  await cameraInput.open();
118
119  // Obtain the supported modes.
120  let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(cameraArray[0]);
121  let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0;
122  if (!isSupportPhotoMode) {
123    console.error('photo mode not support');
124    return;
125  }
126  // Obtain the output streams supported by the camera.
127  let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO);
128  if (!cameraOutputCap) {
129    console.error("cameraManager.getSupportedOutputCapability error");
130    return;
131  }
132  console.info("outputCapability: " + JSON.stringify(cameraOutputCap));
133
134  let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles;
135  if (!previewProfilesArray) {
136    console.error("createOutput previewProfilesArray == null || undefined");
137  }
138
139  let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles;
140  if (!photoProfilesArray) {
141    console.error("createOutput photoProfilesArray == null || undefined");
142  }
143
144  // Create a preview output stream. For details about the surfaceId parameter, see the XComponent. The preview stream uses the surface provided by the XComponent.
145  let previewOutput: camera.PreviewOutput | undefined = undefined;
146  try {
147    previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId);
148  } catch (error) {
149    let err = error as BusinessError;
150    console.error(`Failed to create the PreviewOutput instance. error code: ${err.code}`);
151  }
152  if (previewOutput === undefined) {
153    return;
154  }
155  // Listen for preview output errors.
156  previewOutput.on('error', (error: BusinessError) => {
157    console.error(`Preview output error code: ${error.code}`);
158  });
159  // Create a photo output stream.
160  let photoOutput: camera.PhotoOutput | undefined = undefined;
161  try {
162    photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0]);
163  } catch (error) {
164    let err = error as BusinessError;
165    console.error('Failed to createPhotoOutput errorCode = ' + err.code);
166  }
167  if (photoOutput === undefined) {
168    return;
169  }
170  // Create a session.
171  let photoSession: camera.PhotoSession | undefined = undefined;
172  try {
173    photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
174  } catch (error) {
175    let err = error as BusinessError;
176    console.error('Failed to create the photoSession instance. errorCode = ' + err.code);
177  }
178  if (photoSession === undefined) {
179    return;
180  }
181  // Listen for session errors.
182  photoSession.on('error', (error: BusinessError) => {
183    console.error(`Capture session error code: ${error.code}`);
184  });
185
186  // Start configuration for the session.
187  try {
188    photoSession.beginConfig();
189  } catch (error) {
190    let err = error as BusinessError;
191    console.error('Failed to beginConfig. errorCode = ' + err.code);
192  }
193
194  // Add the camera input stream to the session.
195  try {
196    photoSession.addInput(cameraInput);
197  } catch (error) {
198    let err = error as BusinessError;
199    console.error('Failed to addInput. errorCode = ' + err.code);
200  }
201
202  // Add the preview output stream to the session.
203  try {
204    photoSession.addOutput(previewOutput);
205  } catch (error) {
206    let err = error as BusinessError;
207    console.error('Failed to addOutput(previewOutput). errorCode = ' + err.code);
208  }
209
210  // Add the photo output stream to the session.
211  try {
212    photoSession.addOutput(photoOutput);
213  } catch (error) {
214    let err = error as BusinessError;
215    console.error('Failed to addOutput(photoOutput). errorCode = ' + err.code);
216  }
217
218  // Register a callback to listen for original images.
219  photoOutput.on('photoAvailable', (err: BusinessError, photoObj: camera.Photo): void => {
220    if (err) {
221      console.info(`photoAvailable error: ${JSON.stringify(err)}.`);
222      return;
223    }
224    savePicture(photoObj).then(() => {
225      // Release the photo object after the flushing is complete.
226      photoObj.release();
227    });
228  });
229
230  // Register a callback to listen for thumbnail proxies.
231  photoOutput.on('deferredPhotoProxyAvailable', (err: BusinessError, proxyObj: camera.DeferredPhotoProxy): void => {
232    if (err) {
233      console.info(`deferredPhotoProxyAvailable error: ${JSON.stringify(err)}.`);
234      return;
235    }
236    console.info('photoOutPutCallBack deferredPhotoProxyAvailable');
237    // Obtain the pixel map of a thumbnail.
238    proxyObj.getThumbnail().then((thumbnail: image.PixelMap) => {
239      AppStorage.setOrCreate('proxyThumbnail', thumbnail);
240    });
241    // Call the mediaLibrary API to flush the thumbnail.
242    saveDeferredPhoto(proxyObj).then(() => {
243      // Release the thumbnail proxy class object after the flushing is complete.
244      proxyObj.release();
245    });
246  });
247
248  // Check whether deferred delivery is supported.
249  let isSupportDeferred: boolean = photoOutput.isDeferredImageDeliverySupported(camera.DeferredDeliveryImageType.PHOTO);
250  console.info('isDeferredImageDeliverySupported res:' + isSupportDeferred);
251  if (isSupportDeferred) {
252    // Enable deferred delivery.
253	photoOutput.deferImageDelivery(camera.DeferredDeliveryImageType.PHOTO);
254    // Check whether deferred delivery is enabled.
255    let isSupportEnabled: boolean = photoOutput.isDeferredImageDeliveryEnabled(camera.DeferredDeliveryImageType.PHOTO);
256    console.info('isDeferredImageDeliveryEnabled res:' + isSupportEnabled);
257  }
258
259  // Commit the session configuration.
260  await photoSession.commitConfig();
261
262  // Start the session.
263  await photoSession.start().then(() => {
264    console.info('Promise returned to indicate the session start success.');
265  });
266  // Check whether the camera has flash.
267  let flashStatus: boolean = false;
268  try {
269    flashStatus = photoSession.hasFlash();
270  } catch (error) {
271    let err = error as BusinessError;
272    console.error('Failed to hasFlash. errorCode = ' + err.code);
273  }
274  console.info('Returned with the flash light support status:' + flashStatus);
275
276  if (flashStatus) {
277    // Check whether the auto flash mode is supported.
278    let flashModeStatus: boolean = false;
279    try {
280      let status: boolean = photoSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO);
281      flashModeStatus = status;
282    } catch (error) {
283      let err = error as BusinessError;
284      console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code);
285    }
286    if(flashModeStatus) {
287      // Set the flash mode to auto.
288      try {
289        photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO);
290      } catch (error) {
291        let err = error as BusinessError;
292        console.error('Failed to set the flash mode. errorCode = ' + err.code);
293      }
294    }
295  }
296
297  // Check whether the continuous auto focus is supported.
298  let focusModeStatus: boolean = false;
299  try {
300    let status: boolean = photoSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
301    focusModeStatus = status;
302  } catch (error) {
303    let err = error as BusinessError;
304    console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code);
305  }
306
307  if (focusModeStatus) {
308    // Set the focus mode to continuous auto focus.
309    try {
310      photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
311    } catch (error) {
312      let err = error as BusinessError;
313      console.error('Failed to set the focus mode. errorCode = ' + err.code);
314    }
315  }
316
317  // Obtain the zoom ratio range supported by the camera.
318  let zoomRatioRange: Array<number> = [];
319  try {
320    zoomRatioRange = photoSession.getZoomRatioRange();
321  } catch (error) {
322    let err = error as BusinessError;
323    console.error('Failed to get the zoom ratio range. errorCode = ' + err.code);
324  }
325  if (zoomRatioRange.length <= 0) {
326    return;
327  }
328  // Set a zoom ratio.
329  try {
330    photoSession.setZoomRatio(zoomRatioRange[0]);
331  } catch (error) {
332    let err = error as BusinessError;
333    console.error('Failed to set the zoom ratio value. errorCode = ' + err.code);
334  }
335  let photoCaptureSetting: camera.PhotoCaptureSetting = {
336    quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // Set the photo quality to high.
337    rotation: camera.ImageRotation.ROTATION_0 // Set the rotation angle of the photo to 0.
338  }
339  // Use the current photographing settings to take photos.
340  photoOutput.capture(photoCaptureSetting, (err: BusinessError) => {
341    if (err) {
342      console.error(`Failed to capture the photo ${err.message}`);
343      return;
344    }
345    console.info('Callback invoked to indicate the photo capture request success.');
346  });
347  // Stop the session.
348  photoSession.stop();
349
350  // Release the camera input stream.
351  cameraInput.close();
352
353  // Release the preview output stream.
354  previewOutput.release();
355
356  // Release the photo output stream.
357  photoOutput.release();
358
359  // Release the session.
360  photoSession.release();
361
362  // Set the session to null.
363  photoSession = undefined;
364}
365```
366
367 <!--no_check-->