DEV Community

ShuGang Zhou
ShuGang Zhou

Posted on • Edited on

06-HarmonyOS5-SubjectSegmentation-Case

Case Description

This is a background replacement case based on AI basic visual services. After selecting an image from the device's photo album, it performs intelligent segmentation on the subject and supports dynamically changing the background color.

Implementation Steps:

1. Module Import and Component Definition

import { photoAccessHelper } from '@kit.MediaLibraryKit'
import { fileIo } from '@kit.CoreFileKit'
import image from '@ohos.multimedia.image'
import { subjectSegmentation } from '@kit.CoreVisionKit'
import { promptAction } from '@kit.ArkUI'

@Entry
@ComponentV2
struct SubjectSegmentation {
  @Local chooseImage?: PixelMap  // Original image
  @Local segmentedImage?: PixelMap // Segmented image
  @Local bgColor: ResourceColor = Color.White // Background color state
Enter fullscreen mode Exit fullscreen mode

2. Image Selection and Processing

async segmentImage() {
  if (canIUse('SystemCapability.AI.Vision.SubjectSegmentation')) {
    // Create an image picker
    const photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();

    // Select a single image
    const photoResult = await photoPicker.select({
      MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
      maxSelectNumber: 1
    })

    // Get the image URI and convert it to PixelMap format
    const photoUri = photoResult.photoUris[0]
    const fileSource = await fileIo.open(photoUri, fileIo.OpenMode.READ_ONLY);
    const imageSource = image.createImageSource(fileSource.fd);
    this.chooseImage = await imageSource.createPixelMap();
Enter fullscreen mode Exit fullscreen mode

3. Subject Segmentation Processing

    // Configure visual recognition parameters
    const visionInfo: subjectSegmentation.VisionInfo = {
      pixelMap: this.chooseImage,
    };

    try {
      // Perform subject segmentation
      const result = await subjectSegmentation.doSegmentation(visionInfo, {
        enableSubjectForegroundImage: true
      })
      this.segmentedImage = result.fullSubject.foregroundImage
    } catch (e) {
      promptAction.showToast({ message: e.message })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Background Replacement Mechanism

  build() {
    Column({ space: 20 }) {
      // Original image display area
      Text('Original Image:')
      Image(this.chooseImage)
        .objectFit(ImageFit.Fill)
        .height('30%')

      // Segmented image display area
      Text('Background Removed:')
      Image(this.segmentedImage)
        .objectFit(ImageFit.Fill)
        .height('30%')
        .backgroundColor(this.bgColor)

      // Function operation buttons
      Button('Select Image').onClick(() => this.segmentImage())
      Button('Change Background').onClick(() => {
        // Generate a random RGB background color
        const a = Math.round(Math.random() * 255)
        const b = Math.round(Math.random() * 255)
        const c = Math.round(Math.random() * 255)
        this.bgColor = `rgb(${a},${b},${c})`
      })
    }
    .padding(15)
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Summary:

Key Points

  1. Multimedia library calls to implement image selection and format conversion
  2. The subjectSegmentation.doSegmentation interface completes intelligent subject segmentation
  3. The dynamic background color mechanism is implemented through random RGB values

Complete Code

// Keep the original code provided by the user intact here
import { photoAccessHelper } from '@kit.MediaLibraryKit'
import { fileIo } from '@kit.CoreFileKit'
import image from '@ohos.multimedia.image'
import { subjectSegmentation } from '@kit.CoreVisionKit'
import { promptAction } from '@kit.ArkUI'

@Entry
@ComponentV2
struct SubjectSegmentation {
  @Local chooseImage?: PixelMap
  @Local segmentedImage?: PixelMap
  @Local bgColor: ResourceColor = Color.White

  async segmentImage() {
    if (canIUse('SystemCapability.AI.Vision.SubjectSegmentation')) {
      const photoPicker: photoAccessHelper.PhotoViewPicker = new photoAccessHelper.PhotoViewPicker();
      const photoResult = await photoPicker.select({
        MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
        maxSelectNumber: 1
      })
      const photoUri = photoResult.photoUris[0]
      const fileSource = await fileIo.open(photoUri, fileIo.OpenMode.READ_ONLY);
      const imageSource = image.createImageSource(fileSource.fd);
      this.chooseImage = await imageSource.createPixelMap();
      const visionInfo: subjectSegmentation.VisionInfo = {
        pixelMap: this.chooseImage,
      };
      try {
        const result = await subjectSegmentation.doSegmentation(visionInfo, {
          enableSubjectForegroundImage: true
        })
        this.segmentedImage = result.fullSubject.foregroundImage
      } catch (e) {
        promptAction.showToast({ message: e.message })
      }
    }
  }

  build() {
    Column({ space: 20 }) {
      Text('Original Image:')
      Image(this.chooseImage)
        .objectFit(ImageFit.Fill)
        .height('30%')
      Text('Background Removed:')
      Image(this.segmentedImage)
        .objectFit(ImageFit.Fill)
        .height('30%')
        .backgroundColor(this.bgColor)
      Button('Select Image')
        .onClick(() => this.segmentImage())
      Button('Change Background')
        .onClick(() => {
          const a = Math.round(Math.random() * 255)
          const b = Math.round(Math.random() * 255)
          const c = Math.round(Math.random() * 255)
          this.bgColor = `rgb(${a},${b},${c})`
        })
    }
    .padding(15)
    .height('100%')
    .width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)