Solution
1. Import the image module.
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. This is achieved by calling the APIs provided by the image module.
import { image } from '@kit.ImageKit'; 2. Create a surface of the ImageReceiver object.
async function getImageReceiverSurfaceId(): Promise<string | undefined> {
let receiver: image.ImageReceiver = image.createImageReceiver({ width: 640,height: 480 },4,8);
console.info('before ImageReceiver check');
let ImageReceiverSurfaceId: string | undefined = undefined;
if (receiver !== undefined) {
console.info('ImageReceiver is ok');
let ImageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId();
console.info(`ImageReceived id: ${ImageReceiverSurfaceId}`);
} else {
console.error('ImageReceiver is not ok');
}
return ImageReceiverSurfaceId;
} 3. Create a surface of an XComponent object.
For details, see the camera preview guide.
//xxx.ets
// Create an XComponentController object.
@Entry
@Component
struct XComponentPage {
// Create an XComponentController object.
mXComponentController: XComponentController = new XComponentController;
build() {
Flex() {
// Create XComponent
XComponent({
id: '',
type: 'surface',
libraryname: '',
controller: this.mXComponentController
})
.onLoad(() => {
// Set the width and height of the Surface (1920 * 1080), and set the preview size based on the preview resolution size supported
// by the current device obtained from previewProfilesArray earlier
this.mXComponentController.setXComponentSurfaceRect({surfaceWidth:1920,surfaceHeight:1080});
// Get Surface ID
let surfaceId: string = this.mXComponentController.getXComponentSurfaceId();
})
.width('1920px')
.height('1080px')
}
}
} 4. Implement dual-channel preview.
Call 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.
import { camera } from '@kit.CameraKit';
import { image } from '@kit.ImageKit';
async function createDualChannelPreview(cameraManager: camera.CameraManager, XComponentSurfaceId: string, receiver: image.ImageReceiver): Promise<void> {
let camerasDevices: Array<camera.CameraDevice> = cameraManager.getSupportedCameras(); // Obtain the supported camera devices.
// Get profile object
let profiles: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(camerasDevices[0], camera.SceneMode.NORMAL_PHOTO); // Obtain the profiles of the camera.
let previewProfiles: Array<camera.Profile> = profiles.previewProfiles;
// Preview Stream 1
let previewProfilesObj: camera.Profile = previewProfiles[0];
// Preview Stream 2
let previewProfilesObj2: camera.Profile = previewProfiles[0];
// Create preview stream 1 output object
let previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfilesObj, XComponentSurfaceId);
// Create preview stream 2 output object
let imageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId();
let previewOutput2: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfilesObj2, imageReceiverSurfaceId);
// Create cameraInput object
let cameraInput: camera.CameraInput = cameraManager.createCameraInput(camerasDevices[0]);
// Turn on the camera
await cameraInput.open();
// session flow
let captureSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO);
// Start configuring session
captureSession.beginConfig();
// Add CameraInput to the conversation
captureSession.addInput(cameraInput);
// Add preview stream 1 to the session
captureSession.addOutput(previewOutput);
// Add preview stream 2 to the session
captureSession.addOutput(previewOutput2);
// Submit configuration information
await captureSession.commitConfig();
// session start
await captureSession.start();
} 5. Obtain preview images in real time through the ImageReceiver object.
Use the imageArrival event of the ImageReceiver object to listen for and obtain image data returned by the bottom layer. For details, see the Image API reference.
import { BusinessError } from '@kit.BasicServicesKit';
import image from '@ohos.multimedia.image';
function onImageArrival(receiver: image.ImageReceiver): void {
receiver.on('imageArrival', () => {
receiver.readNextImage((err: BusinessError, nextImage: image.Image) => {
if (err || nextImage === undefined) {
return;
}
// The current ImageReceiver does not support obtaining YUV data. You can use the JPEG data channel to receive YUV data, but using this method carries risks
nextImage.getComponent(image.ComponentType.JPEG, (err: BusinessError, imgComponent: image.Component) => {
if (err || imgComponent === undefined) {
return;
}
if (imgComponent.byteBuffer as ArrayBuffer) {
// Handle according to business demands
} else {
return;
}
})
})
})
} Reference