news 2026/4/23 10:24:54

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙实现自定义类似活体检测功能

一.背景

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

二.实现思路

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

三.代码

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

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

/* * 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) } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:53:05

零基础彻底搞懂:如何把 Java/ES/Redis 程序交给 systemctl 管理

告别 nohup & screen!不用 Docker 也能实现开机自启、崩溃重启、统一日志 适合人群:Linux 新手、Java 开发、运维初学者、学生党❗ 先破除最大误区:.service 不是脚本! 很多新手以为:“我把 xxx.service 写好&…

作者头像 李华
网站建设 2026/4/23 11:45:50

管理者必收藏的10大核心工具,效率翻倍

# 开篇:管理不用 “凭感觉”,工具帮你 “抓本质”不少管理者陷入 “忙而无效” 的困境:目标越定越模糊,问题越解决越复杂,团队越带越涣散。其实,高效管理的核心不是 “拼精力”,而是 “用对工具…

作者头像 李华
网站建设 2026/4/23 11:50:12

ENSP下载官网无法访问?试试离线安装包

ENSP下载官网无法访问?试试离线安装包 在工业自动化与智能视觉系统快速落地的今天,一个看似简单的问题却常常让工程师头疼不已:开发工具官网打不开。比如华为ENSP(Enterprise Network Simulation Platform)这类关键网络…

作者头像 李华
网站建设 2026/4/23 11:45:45

从小白到高手:手把手教你玩转LobeChat所有核心功能

从小白到高手:手把手教你玩转 LobeChat 所有核心功能 在 AI 聊天助手几乎成为数字生活标配的今天,越来越多用户不再满足于“用现成的”,而是希望拥有一个真正属于自己的智能对话系统——不依赖云端、数据可控、功能可定制。OpenAI 的 ChatGPT…

作者头像 李华
网站建设 2026/4/23 11:26:01

Dify在AI应用全生命周期管理中的关键作用

Dify在AI应用全生命周期管理中的关键作用 在企业纷纷拥抱大模型的今天,一个现实问题摆在面前:如何让非算法背景的团队也能高效构建稳定、可控、可维护的AI应用?我们见过太多项目卡在“从Demo到上线”的最后一公里——提示词调不好、知识库更新…

作者头像 李华
网站建设 2026/4/14 17:02:34

卷积神经网络核心原理在YOLO中的精妙运用

卷积神经网络核心原理在YOLO中的精妙运用 在智能制造与边缘计算快速融合的今天,工业相机每秒生成成千上万帧图像,而系统必须在几十毫秒内判断是否存在缺陷、人员闯入或设备异常。面对如此严苛的实时性要求,传统目标检测方法显得力不从心——R…

作者头像 李华