鸿蒙实现自定义类似活体检测功能

一.背景

目前需要实现活体检测功能,而且是需要静默活体,但是现在官方的活体API还不支持静默,第三方的SDK也不支持,现在自定义一个类似活体检测的功能,但是不会去检测是否活体,拿到照片以后去调用人脸识别

二.实现思路

先调用相机,将相机设置为前置摄像头,将当前相机内容使用XComponent实时渲染,启用定时拍照功能,设置定时器,时间到以后利用截图组件功能去做,然后拿到图片地址去进行人脸识别,不保存到本地

三.代码

这边只放了首页代码,其余代码会在包里,在文章后附带

使用的时候将包放到项目中,直接跳转或者引用xsComponent这个页面

TypeScript 复制代码
/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

import { CameraConstants } from './constants/CameraConstants';
import { CameraUtils } from './utils/CameraUtils';
import { abilityAccessCtrl, bundleManager, common, PermissionRequestResult, Permissions } from '@kit.AbilityKit';
import { BusinessError, emitter } from '@kit.BasicServicesKit';
import Logger from './utils/Logger';
import { TwiceReqPermissionButtonComponent } from './component/TwiceReqPermissionButtonComponent';
import { StackXComponent } from './component/StackXComponent';
import LoadingDialog from '@lyb/loading-dialog';
import { DynamicsRouter } from 'common';

@Builder
export function xsIndexBuilder() {
  xsIndex()
}

@Entry
@Component
struct xsIndex {
  @Provide cameraPosition: number = 1; // 固定为前置摄像头
  @Provide notHasPermission: boolean = true;
  @Provide surfaceId: string = '';
  @Provide timerShooting: number = 3; // 固定3秒
  @Provide captureTimer: number = 0;
  @Provide isVisibleTimerSet: boolean = false;
  @Provide isVisibleTimer: boolean = false;
  @Provide isVisibleCapture: boolean = true;
  @Provide captureClickFlag: number = 0;
  @State autoCaptureStarted: boolean = false; // 标记是否已开始自动拍照
  private uiContext: UIContext = this.getUIContext();
  private cameraUtils = new CameraUtils(this.uiContext);

  checkPermissions(permission: Permissions) {
    let atManager = abilityAccessCtrl.createAtManager();
    let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let tokenID = bundleInfo.appInfo.accessTokenId;
    let authResults = atManager.checkAccessTokenSync(tokenID, permission);
    return authResults === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
  }

  aboutToDisappear(): void {
    this.cameraUtils.releaseCamera();
  }

 

    AppStorage.setOrCreate('cameraUtils', this.cameraUtils);
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    let context: Context = this.getUIContext().getHostContext() as common.UIAbilityContext;
    atManager.requestPermissionsFromUser(context, ['ohos.permission.CAMERA'])
      .then((data: PermissionRequestResult) => {
        if (data.authResults[0] === 0) {
          this.notHasPermission = false;
          this.cameraUtils.cameraShooting(this.cameraPosition, this.surfaceId, context);
          // 延迟启动自动拍照,等待相机初始化完成
          setTimeout(() => {
            this.startAutoCapture();
          }, 500);
        } else if (data.authResults[0] === -1) {
          this.notHasPermission = true;
        }
      })
      .catch((err: BusinessError) => {
        Logger.error(`data: ${JSON.stringify(err)}`);
      });
  }

  // 开始自动拍照流程
  startAutoCapture(): void {
    if (this.autoCaptureStarted || this.notHasPermission) {
      return;
    }
    this.autoCaptureStarted = true;
    this.isVisibleTimer = true;
    this.captureTimer = this.timerShooting;
    this.isVisibleCapture = false;

    // 3秒后自动拍照
    setTimeout(() => {
      this.cameraUtils.capture(true); // 前置摄像头需要镜像
      this.captureClickFlag = this.captureClickFlag + 1;
      this.isVisibleCapture = true;
      this.isVisibleTimer = false;
    }, this.captureTimer * 1000);
  }

  onPageShow() {
    if (!this.notHasPermission) {
      let permissions: Permissions = 'ohos.permission.CAMERA';
      if (this.checkPermissions(permissions)) {
        this.cameraUtils.cameraShooting(this.cameraPosition, this.surfaceId, this.getUIContext().getHostContext()!);
        this.notHasPermission = false;
        // 如果还没有开始自动拍照,则启动
        if (!this.autoCaptureStarted) {
          setTimeout(() => {
            this.startAutoCapture();
          }, 500);
        }
      } else {
        this.notHasPermission = true;
      }
    }
  }

  onPageHide(): void {
    if (!this.notHasPermission) {
      this.cameraUtils.releaseCamera();
    }
  }

  build() {
    NavDestination() {
      Column() {
        if (this.notHasPermission) {
          TwiceReqPermissionButtonComponent();
        } else {
          Row() {
            Image($r('app.media.back'))
              .width(25)
              .height(25)
              .onClick(() => {
                DynamicsRouter.pop()
              })
          }.width('100%').padding(15)

          StackXComponent();
        }
      }
      .height(CameraConstants.FULL_SCREEN)
      .width(CameraConstants.FULL_SCREEN)
      .backgroundColor(Color.White) // 白色背景
      .padding({
        top: this.uiContext.px2vp(AppStorage.get('topAvoid')) as number,
        bottom: this.uiContext.px2vp(AppStorage.get('bottomAvoid')) as number
      });
    }.hideBackButton(true)
  }
}
相关推荐
微小冷26 分钟前
海康威视相机C#二次开发环境配置
数码相机·c#·.net·海康威视·相机开发
梦想不只是梦与想1 小时前
鸿蒙 测试工具:DevEco Testing(一)
测试工具·harmonyos·testing
浪里镖客3 小时前
realsense d435i相机所有内外参获得
数码相机
大锅盖13 小时前
Web 工单要调用相机,第一步不是打开取景框,而是建立能力门禁
前端·数码相机·harmonyos
M-Robots echo6 小时前
M-Robots ROS 兼容适配方案,实现存量机器人项目低成本迁移
机器人·ros·鸿蒙·开源社区·m-robots
市象6 小时前
暑期档市占3%,全景相机距离影像主赛道还有点远
数码相机·全景相机·手持影像
微小冷7 小时前
海康威视相机C#二次开发指图像采集
数码相机·c#·二次开发·机器视觉·海康威视·mvs·相机开发
贾伟康7 小时前
【华夏二十四节气|07】HarmonyOS 6.0.2(22) ArkTS 节气搜索实战:多字段匹配与四态闭环
移动开发·harmonyos·arkts·arkui·本地搜索
大龄秃头程序员8 小时前
Flutter 项目鸿蒙适配实战:从环境搭建到多环境打包全指南
harmonyos
贾伟康10 小时前
【万能转换器|18】HarmonyOS ArkTS 权限与隐私实战:让 module.json5、功能说明和拒绝路径一致
移动开发·harmonyos·arkts·权限管理·隐私合规