harmony 鸿蒙Using ImageReceiver to Receive Images

  • 2025-06-12
  • 浏览 (3)

Using ImageReceiver to Receive Images

You can use the ImageReceiver class to obtain the surface ID of a component, read the latest image or the next image, and release ImageReceiver instances. > NOTE > > The ImageReceiver works as a consumer and needs a matching producer to provide data to work properly. Typical producers are the camera’s photo or preview streams.

The ImageReceiver can receive images from the camera’s preview stream, allowing for dual-channel preview.

Read Image for APIs related to ImageReceiver.

How to Develop

Create an ImageReceiver object, obtain the surface ID to create a preview stream, register image listeners, and process each frame of the image in the preview stream as required.

  1. Create an ImageReceiver object, through which you can obtain the surface ID of the preview stream.

    import { image } from '@kit.ImageKit';
    let imageWidth: number = 1920; // Use the width in the profile size supported by the device.
    let imageHeight: number = 1080; // Use the height in the profile size supported by the device.
    
    
    async function initImageReceiver():Promise<void>{
      // Create an ImageReceiver object.
      let size: image.Size = { width: imageWidth, height: imageHeight };
      let imageReceiver = image.createImageReceiver(size, image.ImageFormat.JPEG, 8);
      // Obtain the preview stream surface ID.
      let imageReceiverSurfaceId = await imageReceiver.getReceivingSurfaceId();
      console.info(`initImageReceiver imageReceiverSurfaceId:${imageReceiverSurfaceId}`);
    }
    
  2. Register a listener to process each frame of image data in the preview stream. Specifically, use the imageArrival event in the ImageReceiver object to obtain the image data returned by the bottom layer. For details, see Image API Reference.

    import { BusinessError } from '@kit.BasicServicesKit';
    import { image } from '@kit.ImageKit';
    
    
    function onImageArrival(receiver: image.ImageReceiver): void {
      // Subscribe to the imageArrival event.
      receiver.on('imageArrival', () => {
        // Obtain an image.
        receiver.readNextImage((err: BusinessError, nextImage: image.Image) => {
          if (err||nextImage === undefined) {
            console.error('readNextImage failed');
            return;
          }
          // Parse the image.
          nextImage.getComponent(image.ComponentType.JPEG, async (err: BusinessError, imgComponent: image.Component) => {
            if (err||imgComponent === undefined) {
              console.error('getComponent failed');
            }
            if (imgComponent.byteBuffer) {
              // For details, see the description of parsing the image buffer data below. This example uses method 1.
              let width = nextImage.size.width; // Obtain the image width.
              let height = nextImage.size.height; // Obtain the image height.
              let stride = imgComponent.rowStride; // Obtain the image stride.
              console.debug(`getComponent with width:${width} height:${height} stride:${stride}`);
              // The value of stride is the same as that of width.
              if (stride == width) {
                let pixelMap = await image.createPixelMap(imgComponent.byteBuffer, {
                  size: { height: height, width: width },
                  srcPixelFormat: 8,
                })
              } else {
                // The value of stride is different from that of width.
                const dstBufferSize = width * height * 1.5
                const dstArr = new Uint8Array(dstBufferSize)
                for (let j = 0; j < height * 1.5; j++) {
                  const srcBuf = new Uint8Array(imgComponent.byteBuffer, j * stride, width)
                  dstArr.set(srcBuf, j * width)
                }
                let pixelMap = await image.createPixelMap(dstArr.buffer, {
                  size: { height: height, width: width },
                  srcPixelFormat: 8,
                })
              }
            } else {
              console.error('byteBuffer is null');
            }
            // Release the resource when the buffer is not in use.
            // If an asynchronous operation is performed on the buffer, call nextImage.release() to release the resource after the asynchronous operation is complete.
            nextImage.release();
          })
        })
      })
    }
    

    The following methods are available for parsing the image buffer data by using image.Component.

    NOTE

    Check whether the width of the image is the same as rowStride. If they are different, perform the following operations:

    Method 1: Remove the stride data from imgComponent.byteBuffer, obtain a new buffer by means of copy, and process the buffer by calling the API that does not support stride.

    // For example, for NV21 (images in YUV_420_SP format), the formula for calculating the YUV_420_SP memory is as follows: YUV_420_SP memory = Width * Height + (Width * Height)/2.
    const dstBufferSize = width * height * 1.5;
    const dstArr = new Uint8Array(dstBufferSize);
    // Read the buffer data line by line.
    for (let j = 0; j < height * 1.5; j++) {
      // Copy the first width bytes of each line of data in imgComponent.byteBuffer to dstArr.
      const srcBuf = new Uint8Array(imgComponent.byteBuffer, j * stride, width);
      dstArr.set(srcBuf, j * width);
    }
    let pixelMap = await image.createPixelMap(dstArr.buffer, {
      size: { height: height, width: width }, srcPixelFormat: 8
    });
    

    Method 2: Create a PixelMap based on the value of stride * height, and call cropSync of the PixelMap to crop redundant pixels.

    // Create a PixelMap, with width set to the value of stride.
    let pixelMap = await image.createPixelMap(imgComponent.byteBuffer, {
      size:{height: height, width: stride}, srcPixelFormat: 8});
    // Crop extra pixels.
    pixelMap.cropSync({size:{width:width, height:height}, x:0, y:0});
    

    Method 3: Pass imgComponent.byteBuffer and stride to the API that supports stride.

你可能感兴趣的鸿蒙文章

harmony 鸿蒙Image Kit

harmony 鸿蒙Allocating Memory for Image Decoding (C/C++)

harmony 鸿蒙Allocating Memory for Image Decoding (ArkTS)

harmony 鸿蒙Image Decoding

harmony 鸿蒙Using ImageSource to Decode Images

harmony 鸿蒙Using ImageEffect to Edit Images

harmony 鸿蒙Image Encoding

harmony 鸿蒙Using ImagePacker to Encode Images

harmony 鸿蒙Using Image_NativeModule to Process Image Information

harmony 鸿蒙Introduction to Image Kit

0  赞