Case Description
This is a face comparison case implemented based on AI basic vision services. By selecting two images from the device's photo album, it performs face feature comparison and displays the similarity calculation result.
Implementation Steps:
1. Module Import
// Import functional modules
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { image } from '@kit.ImageKit';
import { faceComparator } from '@kit.CoreVisionKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
2. Dual-Image Selection Function
// Create a common image selection method
async chooseImage (): Promise<PixelMap> {
const photoPicker = new photoAccessHelper.PhotoViewPicker();
const photoResult = await photoPicker.select({
MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
maxSelectNumber: 1
})
// Get the file handle of the selected image
const fileSource = await fileIo.open(photoResult.photoUris[0], fileIo.OpenMode.READ_ONLY);
// Generate pixel map format data
return await image.createImageSource(fileSource.fd).createPixelMap();
}
3. Image Processing Flow
// Define dual-image storage variables
@Local chooseImage1?: PixelMap
@Local chooseImage2?: PixelMap
// Image click processing logic
.onClick(async () => {
const chooseImage = await this.chooseImage()
this.chooseImage1 = chooseImage // Store the first image
})
.onClick(async () => {
const chooseImage = await this.chooseImage()
this.chooseImage2 = chooseImage // Store the second image
})
4. Core Implementation of Face Comparison
// Configure dual-image comparison parameters
let visionInfo: faceComparator.VisionInfo = {
pixelMap: this.chooseImage1,
};
let visionInfo1: faceComparator.VisionInfo = {
pixelMap: this.chooseImage2,
};
// Perform face feature comparison
faceComparator.compareFaces(visionInfo, visionInfo1)
.then(result => {
// Show the similarity result in a dialog
promptAction.showDialog({ message: JSON.stringify(result) })
})
.catch((e: BusinessError) => {
// Show error information
promptAction.showToast({ message: e.message })
})
5. Display of Detection Results
// Show the structured comparison result in a dialog
promptAction.showDialog({
message: JSON.stringify({
similarity: 0.92, // Example similarity value
isSamePerson: true // Whether it's the same person
})
})
Implementation Code:
1. UI Component Definition
@Entry
@ComponentV2
struct FaceComparator {
@Local chooseImage1?: PixelMap
@Local chooseImage2?: PixelMap
2. Main Function Method
// Integrate the complete logic of dual-image selection and feature comparison
async chooseImage(): Promise<PixelMap> {
// Complete selection logic...
}
3. Interface Construction
build() {
Column({ space: 20 }) {
Image(this.chooseImage1)
.onClick(/* Select the first image */)
Image(this.chooseImage2)
.onClick(/* Select the second image */)
Button('Face Comparison')
.onClick(/* Trigger the comparison logic */)
}
}
Summary:
Key Points
- Photo album access permission is required.
- Dual-image selection is managed using independent storage variables.
- The compareFaces interface returns the similarity (0-1) and feature point data.
- Device compatibility issues are captured through BusinessError for exception handling.
Complete Code
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { fileIo } from '@kit.CoreFileKit';
import { image } from '@kit.ImageKit';
import { faceComparator } from '@kit.CoreVisionKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@ComponentV2
struct FaceComparator {
@Local chooseImage1?: PixelMap
@Local chooseImage2?: PixelMap
async chooseImage (): Promise<PixelMap> {
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);
const chooseImage = await imageSource.createPixelMap();
return chooseImage
}
build() {
Column({ space: 20 }) {
Image(this.chooseImage1)
.alt($r('sys.media.save_button_picture'))
.width(200)
.aspectRatio(1)
.onClick(async () => {
const chooseImage = await this.chooseImage()
this.chooseImage1 = chooseImage
})
Image(this.chooseImage2)
.alt($r('sys.media.save_button_picture'))
.width(200)
.aspectRatio(1)
.onClick(async () => {
const chooseImage = await this.chooseImage()
this.chooseImage2 = chooseImage
})
Button('Face Comparison')
.id('FaceComparatorButton')
.onClick(async () => {
if (this.chooseImage1 && this.chooseImage2) {
let visionInfo: faceComparator.VisionInfo = {
pixelMap: this.chooseImage1,
};
let visionInfo1: faceComparator.VisionInfo = {
pixelMap: this.chooseImage2,
};
faceComparator.compareFaces(visionInfo, visionInfo1)
.then(result => {
promptAction.showDialog({ message: JSON.stringify(result) })
})
.catch((e: BusinessError) => {
promptAction.showToast({ message: e.message })
})
}
})
}
.padding(15)
.height('100%')
.width('100%')
}
}
Top comments (0)