wxml
< view> < view class = "flex white" > < ! -- 镜头翻转 -- > < view bindtap= "reverse" > 镜头翻转< / view> < view bindtap= "clickScanCode" > 扫二维码< / view> < / view> < view class = "head-image-box w-100 text-center position-relative" > < ! -- resolution:获取人脸图片后的清晰度 low: 低 -- > < camera device- position= "{{devicePosition ?'back': 'front'}}" class = "camera" flash= "off" resolution= 'low' / > < view class = "title" > { { tipsText } } 1 < / view> < image src= "{{faceImage}}" mode= "" / > < cover- view class = "cover-box" wx : if = "{{isShow}}" > < ! -- < cover- image class = "image-box" src= "@/static/images/camera_verify.png" > < / cover- image> -- > < ! -- cover- view 不支持动画所以只能变通的形式实现 -- > < ! -- < cover- image : style= "'transform: translateY('+translateY+'rpx);'" class = "line" src= "@/static/images/bg_line.png" > < / cover- image> -- > < ! -- < cover- view class = "line" > < / cover- view> -- > < / cover- view> < canvas id= "myCanvas" canvas- id= "myCanvas" : style= "'width:'+screenWidth+'px;'+'height:'+screenHeight+'px'" > < / canvas> < / view>
< / view>
js
Page ( { data ( ) { return { isShow : false , tipsText : '' , tempImg : '' , cameraEngine : null , devicePosition : false , isAuthCamera : true , isVerify : false , translateY : - 24 , timer : null , isFlag : true , origin : null , base64 : "" , personId : "" , isFlag2 : true , screenWidth : 375 , screenHeight : 640 , faceImage : '' , } } , onShow : function ( ) { this . setData ( { isVerify : false , tipsText : "" , isFlag : true , } ) this . lineAnimation ( ) ; } , onLoad ( options ) { this . initData ( ) ; } , onUnload ( ) { this . clearTimer ( ) ; } , onHide ( ) { this . clearTimer ( ) ; } , clearTimer ( ) { if ( this . data. timer) { clearInterval ( this . data. timer) ; this . setData ( { timer : null , } ) } this . setData ( { isFlag : false , } ) } , initData ( ) { wx. initFaceDetect ( ) ; this . setData ( { cameraEngine : wx. createCameraContext ( ) , isShow : true , } ) const listener = this . data. cameraEngine. onCameraFrame ( ( frame ) => { console. log ( 888888888 , frame. data, frame. width, frame. height) if ( this . data. isVerify) return if ( this . data. isFlag2) { this . setData ( { isFlag2 : false , screenWidth : frame. width, screenHeight : frame. height, } ) } wx. faceDetect ( { frameBuffer : frame. data, width : frame. width, height : frame. height, enablePoint : true , enableConf : true , enableAngle : true , enableMultiFace : true , success : async ( faceData ) => { console. log ( 1111 , faceData) let face = faceData. faceInfo[ 0 ] if ( face. x == - 1 || face. y == - 1 ) { this . setData ( { tipsText : '检测不到人' } ) } if ( faceData. faceInfo. length > 1 ) { this . setData ( { tipsText : '请保证只有一个人' } ) } else { const { pitch, roll, yaw} = face. angleArray; const standard = 0.5 if ( Math. abs ( pitch) >= standard || Math. abs ( roll) >= standard || Math. abs ( yaw) >= standard) { this . setData ( { tipsText : '请平视摄像头' } ) } else if ( face. confArray. global <= 0.8 || face. confArray. leftEye <= 0.8 || face. confArray. mouth <= 0.8 || face. confArray. nose <= 0.8 || face. confArray. rightEye <= 0.8 ) { this . setData ( { tipsText : '请勿遮挡五官' } ) } else { if ( this . isVerify) return var centerWidth = 250 ; var centerHeight = 250 ; if ( face. x > ( frame. width - centerWidth) / 2 && face. x < ( frame. width - centerWidth) / 2 + centerWidth && face. y > ( frame. height - centerHeight) / 2 && face. y < ( frame. height - centerHeight) / 2 + centerHeight) { this . setData ( { tipsText : '校验中...' , isVerify : true } ) setTimeout ( async ( ) => { let img = await this . changeDataToBase64 ( frame) ; this . setData ( { base64 : img} ) this . searchUserFace ( ) ; } , 300 ) } else { this . setData ( { tipsText : '请将人脸对准中心位置' } ) } } } } , fail : ( err ) => { console. log ( 2222 , err) if ( this . isVerify) return if ( err. x == - 1 || err. y == - 1 ) { this . setData ( { tipsText : '检测不到人' } ) } else { this . setData ( { tipsText : err. errMsg || '网络错误,请退出页面重试' } ) } } , } ) } ) listener. start ( ) this . setData ( { listener : listener} ) } , reverse ( ) { let a = this . data. devicePositionthis . setData ( { devicePosition : ! a} ) } , clickScanCode ( ) { wx. scanCode ( { onlyFromCamera : true , success : ( res ) => { var data = JSON . parse ( res. result. replace ( / \ufeff / g , "" ) ) ; } } ) ; } , changeDataToBase64 ( frame ) { console. log ( 4444 , frame) return new Promise ( ( resolve, reject ) => { var data = new Uint8Array ( frame. data) ; var clamped = new Uint8ClampedArray ( data) ; let that = this ; var width = this . data. screenWidth; var height = frame. height * this . data. screenWidth / frame. width; wx. canvasPutImageData ( { canvasId : 'myCanvas' , x : 0 , y : 0 , width : frame. width, height : frame. height, data : clamped, success ( res ) { console. log ( 5555 , res) wx. canvasToTempFilePath ( { x : 0 , y : 0 , width : width, height : height, canvasId : 'myCanvas' , fileType : 'jpg' , destWidth : width, destHeight : height, quality : 0.5 , success ( res ) { console. log ( 666 , res) wx. getFileSystemManager ( ) . readFile ( { filePath : res. tempFilePath, encoding : 'base64' , success : res => { console. log ( 7777 , res) resolve ( res. data) ; } } ) } , fail ( res ) { console. log ( 8888 , res) reject ( false ) ; } } ) ; } , fail ( error ) { console. log ( error) ; } } ) } ) } , searchUserFace ( ) { console. log ( 333 , this . data. base64) this . setData ( { faceImage : 'data:image/jpeg;base64,' + this . data. base64, tipsText : '校验成功' } ) wx. stopFaceDetect ( ) ; this . data. listener. stop ( ) ; return var params = { faceImage : this . data. base64, } searchFaces ( params) . then ( res => { console. log ( 444 , res) if ( res. code == 200 ) { wx. stopFaceDetect ( ) ; this . data. listener. stop ( ) ; this . clickPushDetail ( res. data. personCode) ; this . setData ( { tipsText : '校验成功' } ) } } ) . catch ( error => { setTimeout ( ( ) => { this . setData ( { isVerify : 'false' } ) } , 500 ) this . setData ( { tipsText : '暂未查找到相关人员' } ) } ) } , clickPushDetail ( ) { } , lineAnimation ( ) { if ( this . timer) return this . setData ( { timer : setInterval ( ( ) => { this . setData ( { translateY : this . data. translateY + 8 } ) if ( this . data. translateY >= 460 ) { this . setData ( { translateY : 10 } ) } } , 40 ) } ) } , onPullDownRefresh ( ) { } , onReachBottom ( ) { } , onShareAppMessage ( ) { }
} )
css
page { background- color: #000000 ;
} . camera- change- image { width : 52rpx; margin- left: 40rpx;
} . scan- image { width : 48rpx;
} . update- box { color : #ffffff;
} . operation- box { position : fixed; width : 100 % ; bottom : calc ( 120rpx + env ( safe- area- inset- bottom) ) ; } . icon- box { width : 76rpx; height : 76rpx; } first { width : 72rpx; height : 72rpx;
} . head- image- box { position : absolute; top : 10vh; color : white; } . camera { width : 750rpx; height : 872rpx; position : relative; z- index: 10 ;
} #myCanvas { position : absolute; z- index: 1 ; top : - 10000px;
} . title { font- size: 40rpx; margin- top: 60rpx;
} . cover- box { position : absolute; top : 40 % ; left : 50 % ; transform : translate ( - 50 % , - 50 % ) ; width : 500rpx; height : 500rpx;
} . image- box { width : 100 % ; height : 100 % ;
} . line { position : absolute; top : 0rpx; left : 8rpx; right : 8rpx; width : auto; height : 30rpx; z- index: 2 ;
}