• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Dual-Channel Preview (ArkTS)
2
3The camera application controls the camera hardware to implement basic operations such as image display (preview), photo saving (photographing), and video recording. The camera model is developed on the surface model. That is, an application transfers data through the surface. Specifically, it obtains the photo stream through the surface of an **ImageReceiver** object and the preview stream through the surface of an **\<XComponent>** object.
4
5To implement dual-channel preview (there are two preview streams instead of one preview stream plus one photo stream), you must create a **previewOutput** object through the surface of an **ImageReceiver** object. Other processes are the same as those of the photo stream and preview stream.
6
7Read [Camera](../reference/apis-camera-kit/js-apis-camera.md) for the API reference.
8
9## Constraints
10
11-  Currently, streams cannot be dynamically added. In other words, you cannot call [addOutput](../reference/apis-camera-kit/js-apis-camera.md#addoutput11) to add streams without calling [session.stop](../reference/apis-camera-kit/js-apis-camera.md#stop11) first.
12- After an **ImageReceiver** object processes image data obtained, it must release the image buffer so that the buffer queue of the surface properly rotates.
13
14## API Calling Process
15
16The figure below shows the recommended API calling process of the dual-channel preview solution.
17
18![dual-preview-streams-instructions](figures/dual-preview-streams-instructions.png)
19
20## How to Develop
21
221. Import the image module.
23
24   Create a surface for the dual-channel preview stream. In addition to the surface of an **\<XComponent>** object, the surface ID generated by an **ImageReceiver** object is needed. The APIs provided by the image module are also needed.
25
26   ```ts
27   import image from '@ohos.multimedia.image';
28   ```
292. Create an **ImageReceiver** object.
30   ```ts
31   let size: image.Size = {
32       width: 640,
33       height: 480
34     }
35   let receiver: image.ImageReceiver = image.createImageReceiver(size, image.ImageFormat.JPEG, 8);
36   ```
373. Obtain the surface ID of the **ImageReceiver** object.
38
39   ```ts
40   async function getImageReceiverSurfaceId(receiver: image.ImageReceiver): Promise<string | undefined> {
41     let ImageReceiverSurfaceId: string | undefined = undefined;
42     if (receiver !== undefined) {
43       console.info('receiver is not undefined');
44       let ImageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId();
45       console.info(`ImageReceived id: ${ImageReceiverSurfaceId}`);
46     } else {
47       console.error('createImageReceiver failed');
48     }
49     return ImageReceiverSurfaceId;
50   }
51   ```
52
534. Create a surface of an **\<XComponent>** object.
54
55   For details, see [Camera Preview](camera-preview.md).
56
57   ```ets
58   //xxx.ets
59   // Create an XComponentController object.
60   @Component
61   struct XComponentPage {
62     // Create an XComponentController object.
63     mXComponentController: XComponentController = new XComponentController;
64
65     build() {
66       Flex() {
67         // Create an XComponent object.
68         XComponent({
69           id: '',
70           type: 'surface',
71           libraryname: '',
72           controller: this.mXComponentController
73         })
74           .onLoad(() => {
75             // Set the surface width and height (1920 x 1080). For details about how to set the preview size, see the preview resolutions supported by the current device, which are obtained from previewProfilesArray.
76             this.mXComponentController.setXComponentSurfaceSize({surfaceWidth:1920,surfaceHeight:1080});
77             // Obtain the surface ID.
78             let surfaceId: string = this.mXComponentController.getXComponentSurfaceId();
79           })
80           .width('1920px')
81           .height('1080px')
82       }
83     }
84   }
85   ```
86
875. Implement dual-channel preview.
88
89   Call [createPreviewOutput](../reference/apis-camera-kit/js-apis-camera.md#createpreviewoutput) to transfer the two surface IDs generated in steps 2 and 3 to the camera service to create two preview streams. Develop other processes based on the normal preview process.
90
91   ```ts
92   import camera from '@ohos.multimedia.camera';
93
94   async function createDualChannelPreview(cameraManager: camera.CameraManager, XComponentSurfaceId: string, receiver: image.ImageReceiver): Promise<void> {
95     // Obtain the supported camera devices.
96     let camerasDevices: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
97
98     // Obtain the supported modes.
99     let sceneModes: Array<camera.SceneMode> = cameraManager.getSupportedSceneModes(camerasDevices[0]);
100     let isSupportPhotoMode: boolean = sceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0;
101     if (!isSupportPhotoMode) {
102       console.error('photo mode not support');
103       return;
104     }
105
106     // Obtain the profile object.
107     let profiles: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(camerasDevices[0], camera.SceneMode.NORMAL_PHOTO); // Obtain the profiles of the camera.
108     let previewProfiles: Array<camera.Profile> = profiles.previewProfiles;
109
110     // Preview stream 1.
111     let previewProfilesObj: camera.Profile = previewProfiles[0];
112
113     // Preview stream 2.
114     let previewProfilesObj2: camera.Profile = previewProfiles[0];
115
116     // Create an output object for preview stream 1.
117     let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfilesObj, XComponentSurfaceId);
118
119     // Create an output object for preview stream 2.
120     let imageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId();
121     let previewOutput2: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfilesObj2, imageReceiverSurfaceId);
122
123     // Create a CameraInput object.
124     let cameraInput: camera.CameraInput = cameraManager.createCameraInput(camerasDevices[0]);
125
126     // Open the camera.
127     await cameraInput.open();
128
129     // Create a session.
130     let photoSession: camera.PhotoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
131
132     // Start configuration for the session.
133     photoSession.beginConfig();
134
135     // Add the CameraInput object to the session.
136     photoSession.addInput(cameraInput);
137
138     // Add preview stream 1 to the session.
139     photoSession.addOutput(previewOutput);
140
141     // Add preview stream 2 to the session.
142     photoSession.addOutput(previewOutput2);
143
144     // Commit the configuration.
145     await photoSession.commitConfig();
146
147     // Start the session.
148     await photoSession.start();
149   }
150   ```
151
1526. Obtain preview images in real time through the **ImageReceiver** object.
153
154   Use the **imageArrival** event of the **ImageReceiver** object to listen for and obtain image data returned by the bottom layer. For details, see [Image](../reference/apis-image-kit/js-apis-image.md).
155
156   ```ts
157   import { BusinessError } from '@ohos.base';
158
159   function onImageArrival(receiver: image.ImageReceiver): void {
160     receiver.on('imageArrival', () => {
161       receiver.readNextImage((err: BusinessError, nextImage: image.Image) => {
162         if (err || nextImage === undefined) {
163           console.error('readNextImage failed');
164           return;
165         }
166         nextImage.getComponent(image.ComponentType.JPEG, (err: BusinessError, imgComponent: image.Component) => {
167           if (err || imgComponent === undefined) {
168             console.error('getComponent failed');
169           }
170           if (imgComponent && imgComponent.byteBuffer as ArrayBuffer) {
171             // do something...
172           } else {
173             console.error('byteBuffer is null');
174           }
175           nextImage.release();
176         })
177       })
178     })
179   }
180   ```
181