更新记录
1.2.0(2026-05-20)
新增功能
- 正脸检测:可要求 pitch / yaw / roll 三轴欧拉角接近 0°,偏转过大时通过
code=2 提示。
- 活体检测:支持单一或组合活体(眨眼、抬头、低头、转头、头从左往右转、头从右往左转),按
livenessActions 顺序依次完成,全部通过后才会触发 code=1。
- 预览椭圆裁剪:
isClipToOval 控制预览区域是否裁剪为椭圆(默认 true,与历史行为一致)。
- 状态回调增强:
code=2 时除文案 message 外,增加 type、completedLivenessActions,便于区分人脸状态、活体进度与已完成动作。
startCamera 传入参数(FaceRect)
| 参数 |
类型 |
默认值 |
说明 |
x |
number |
(必填) |
预览区域左上角 X(px) |
y |
number |
(必填) |
预览区域左上角 Y(px) |
width |
number |
(必填) |
预览区域宽度(px) |
height |
number |
(必填) |
预览区域高度(px) |
isAllowMultiFace |
boolean |
false |
是否允许多张人脸。为 true 时检测到多张人脸会回调 code=2,type 为 MULTI_FACE |
isFaceMustCentered |
boolean |
true |
是否要求人脸居中。为 true 时未居中仅回调 code=2(FACE_NOT_CENTERED),居中且其它条件满足后才 code=1 |
isDrawDetectionBox |
boolean |
true |
是否在预览上绘制人脸检测框 |
isClipToOval |
boolean |
true |
是否将预览视图裁剪为椭圆形 |
isMustFrontFace |
boolean |
false |
是否要求正脸(三轴欧拉角接近 0°) |
frontFaceMaxAngle |
number |
15 |
正脸允许的最大欧拉角偏差(度),三轴共用 |
isLivenessEnabled |
boolean |
false |
是否启用活体。须为 true 且 livenessActions 非空才进入活体流程 |
livenessActions |
Array<LivenessActionName> |
[] |
活体动作序列,按数组顺序依次完成。可选值见下表 |
livenessHeadAngleThreshold |
number |
15 |
抬头 / 低头 / 转头触发阈值(度),三轴共用,建议 15° ~ 25° |
livenessHeadCenterTolerance |
number |
8 |
TURN_LEFT_TO_RIGHT / TURN_RIGHT_TO_LEFT 经过正中央时的 yaw 容差(度),须小于 livenessHeadAngleThreshold,建议 6° ~ 10° |
livenessEyeOpenProb |
number |
0.7 |
眨眼:眼睛「睁开」判定概率下界(ML Kit eyeOpenProbability,0~1) |
livenessEyeClosedProb |
number |
0.3 |
眨眼:眼睛「闭合」判定概率上界 |
livenessActions 可选值(LivenessActionName)
| 值 |
说明 |
BLINK |
眨眼(open → close → open) |
HEAD_UP |
抬头 |
HEAD_DOWN |
低头 |
TURN_LEFT |
脸朝左转 |
TURN_RIGHT |
脸朝右转 |
TURN_LEFT_TO_RIGHT |
头缓慢从左往右转一圈 |
TURN_RIGHT_TO_LEFT |
头缓慢从右往左转一圈 |
回调传出参数(FaceDetectResult)
| 字段 |
类型 |
何时有值 |
说明 |
code |
number |
始终 |
-1 失败;0 摄像头已打开;1 检测成功(含活体全部通过后);2 状态提示 |
message |
string |
多数情况 |
失败原因、成功说明,或 code=2 时展示给用户的提示文案 |
absolutePath |
string |
code=1 |
人脸抓拍临时文件绝对路径 |
type |
string |
code=2 |
消息类型,见下表 |
completedLivenessActions |
Array<string> |
code=2 |
已通过的活体动作名称列表(与 LivenessAction 枚举名一致);非活体或未启用活体时为空数组 |
code=2 时 type 常见取值
type |
说明 |
FACE_INCOMPLETE |
人脸不完整 / 未检测到关键特征点 |
FACE_NOT_FRONT |
未检测到正脸 |
FACE_NOT_CENTERED |
人脸未居中 |
MULTI_FACE |
检测到多张人脸 |
LIVENESS_ALL_COMPLETED |
全部活体动作已完成 |
BLINK / HEAD_UP / … |
活体进行中,当前待完成的动作名(与 livenessActions 中枚举名相同) |
1.1.1(2026-05-14)
修复传入参数 isFaceMustCentered 为 false 时,人脸只显示部分就判定识别成功的问题
1.1.0(2026-05-08)
新增:打开摄像头方法(StartCamera)的传入参数对象增加(isAllowMultiFace,isFaceMustCentered,isDrawDetectionBox)传入参数,具体使用方法可以参考示例
查看更多
平台兼容性
uni-app(4.76)
| Vue2 |
Vue2插件版本 |
Vue3 |
Vue3插件版本 |
Chrome |
Safari |
app-vue |
app-vue插件版本 |
app-nvue |
Android |
Android插件版本 |
iOS |
鸿蒙 |
| √ |
1.0.0 |
√ |
1.0.0 |
× |
× |
√ |
1.0.0 |
- |
5.0 |
1.0.0 |
× |
× |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| × |
× |
× |
× |
× |
× |
× |
× |
× |
- |
× |
× |
uni-app x(4.76)
| Chrome |
Safari |
Android |
Android插件版本 |
iOS |
鸿蒙 |
微信小程序 |
| × |
× |
5.0 |
1.0.0 |
× |
× |
× |
其他
本插件为基于 google mlkit 的摄像头人脸注册与检测(支持活体检测)的 UTS Android 插件
使用场景有以下两种:
1.人脸注册
开发者通过本插件可以直接调用 Android 设备的摄像头,并嵌入到当前页面的指定位置,将自动检测人脸。如果识别到人脸,会调用回调函数一次,传递人脸照片临时文件的url,此时开发者应调用插件的stopCamera 方法关闭摄像头,并上传人脸照片到服务器进行人脸注册。如果注册成功则应调用插件的 deleteFile 方法来删除临时文件;如果注册失败,则应重新调用打开摄像头的方法,重新打开摄像头
2.人脸识别登录
开发者通过本插件可以直接调用 Android 设备的摄像头,并嵌入到当前页面的指定位置,将自动检测人脸。如果识别到人脸,会调用回调函数一次,传递人脸照片临时文件的url。此时开发者可上传人脸照片到服务器进行人脸比对和登录,比对失败或者网络异常的原因导致登录流程中断时,应调用本插件提供的 continueDetect 函数再次允许检测人脸成功后的持续回调。
可查看示例工程中的两个页面,其中:
1.index.vue 演示了人脸录入功能
2.face_detect.vue 演示了人脸识别功能
import { startCamera as utsStartCamera, stopCamera, deleteFile,continueDetect } from '@/uni_modules/lhio-face-detect'
utsStartCamera({
x: left,
y: top+topInfo.fullHeaderHeight,
width: width,
height: height,
isAllowMultiFace:true, //是否允许多张人脸,如果设置为true,识别到多张人脸时会回调 {code:2}
isDrawDetectionBox:true, //是否绘制人脸识别框
isFaceMustCentered:false, // 是否人脸必须居中,如果设置为true,识别到的人脸必须居中才会回调 {code:1}
isClipToOval:true, // 是否将预览视图裁剪为椭圆形
isMustFrontFace:false, // 是否要求正脸
frontFaceMaxAngle:15, // 正脸允许的最大欧拉角偏差,单位:度
isLivenessEnabled:false, // 是否启用活体检测,需要同时配置 livenessActions
livenessActions:['BLINK'], // 活体动作:BLINK、HEAD_UP、HEAD_DOWN、TURN_LEFT、TURN_RIGHT、TURN_LEFT_TO_RIGHT、TURN_RIGHT_TO_LEFT
livenessHeadAngleThreshold:15, // 抬头、低头、转头触发阈值,单位:度
livenessHeadCenterTolerance:8, // 左右连续转头经过正中央的 yaw 容差,单位:度
livenessEyeOpenProb:0.7, // 眨眼时眼睛睁开概率下界
livenessEyeClosedProb:0.3 // 眨眼时眼睛闭合概率上界
}, (res) => {
console.log(res);
if (res.code === -1) {
//打开摄像头失败
uni.showToast({
icon:'none',
title: res.message
})
}else if(res.code === 1 ){
console.log('onFaceDetected');
const filePath = res.absolutePath ?? '';
uni.showToast({
icon:'none',
title: '检测到人脸咯,人脸识别登录中'
})
setTimeout(()=>{
if (filePath) {
//这里是调用接口后删除本地临时文件
deleteFile(filePath);
}
//网络异常时或登录失败,重新启用人脸检测
continueDetect();
//登录成功则关闭摄像头,再进行跳转
//stopCamera();
},3000);
}else if(res.code === 2){
// res.type:FACE_INCOMPLETE、FACE_NOT_FRONT、FACE_NOT_CENTERED、MULTI_FACE、
// LIVENESS_ALL_COMPLETED、LIVENESS_RESET,或活体进行中的动作名(如 BLINK)
// res.completedLivenessActions:已通过的活体动作名称列表
//持续的消息提示,可以自行调整频率
if(!isShowFaceDetectMsg.value){
isShowFaceDetectMsg.value = true;
uni.showToast({
icon:'none',
title: res.message
})
setTimeout(()=>{
isShowFaceDetectMsg.value = false;
},2000)
}
}
});
const submitFace = ()=>{
//通过 faceImgUrl.value 或者 filePath.value 提交照片到服务器进行人脸录入
uni.showToast({
icon:'none',
title: '通过 faceImgUrl.value 或者 filePath.value 提交照片到服务器进行人脸录入'
})
//上传完毕记得删除临时文件
if (filePath.value) {
deleteFile(filePath.value);
}
}