在微信小程序加入百度人脸识别登陆系统,简直是一步一坑。在网上查找了不少文章,经过几天的连续奋战,终于基本实现了这个功能。或许还有不少BUG,但是已经能完成我想要的功能了。在此贴出前后端完整代码。并对每条语句详细说明下。相信对自己以后做类似程序会有所帮助吧。
先上大家最关心的后台PHP代码吧。这个才是重点。。。前台微信小程序端其实很简单了。

首先需要进入百度人脸库下载PHP ,只需要以下SDK目录结构的文件就行了。

PHP后端代码:(我创建了两个PHP页面)

A.PHP 负责图片上传及图片识别

<?php 
//百度人脸入库
/**第一个坑: 注释不能写在“<?php前面或者在<?php前面留空行。不是在小程序端会原样输出,,这样就无法正确读取您想要的数据了” **/ 
$user_id = $_POST['user_id'];   //小程序端传入的用户名
date_default_timezone_set("Asia/Shanghai"); //设置时区
$code = $_FILES['file'];//获取小程序传来的图片
if(is_uploaded_file($_FILES['file']['tmp_name'])) {
//把文件转存到你希望的目录
    $uploaded_file=$_FILES['file']['tmp_name'];
//我们给每个用户动态的创建一个文件夹$user_path=$_SERVER['DOCUMENT_ROOT']."uploadphoto/hwphoto/userface";
//判断该用户文件夹是否已经有这个文件夹
    if(!file_exists($user_path)) {
        mkdir($user_path);
    }
//上传上来的文件名
    $file_true_name=$_FILES['file']['name'];
//文件需要保存的本地路径
    $move_to_file=$user_path."/".date("Y-m-d")."-".uniqid().substr($file_true_name,strrpos($file_true_name,"."));
//保存文件   
 move_uploaded_file($uploaded_file,iconv("utf-8","gb2312",$move_to_file));
}
//需要定义一个类,名字随意
class post{
//入口函数
private function init_face(){
        $APP_ID = 'XXXXX';
        $API_KEY = 'XXXXXXX';
        $SECRET_KEY = 'XXXXXXXXXXXXX';
        require_once  '/www/wwwroot/WWW.XXX.COM/AipFace.php';
        return new \AipFace($APP_ID,$API_KEY,$SECRET_KEY);
    }
//验证照片
public function facevalid(){
//这里需要把类以外的变量定义为全局变量,不是在类里的函数根本找不到“第二坑”
	global $move_to_file;
	global $user_id;
//定义这个变量就是填坑的意思了,其实不用定义这个变量了
	$userId ="$user_id";
    $file = "$move_to_file"; //照片服务器路径
    if(!file_exists($file)){
        die('文件不存在');
    }
//获取上传的图片并转换成64位的,百度人脸识别要求的
    $image = file_get_contents($file);
    $image = base64_encode($image);
//可选项,必须是数组形式
    $options = array();
//最大人脸数不能超过2个
    $options['max_face_num'] = 2;
//这个完全是搞起玩的。这行代码可以忽略,判断下年龄,评分,性别
    $options['face_field'] = 'age,beauty,gender';
//调取入口函数
    $client = $this->init_face();
//通过入口函数调用人脸识别方法,传入要求的参数
    $ret = $client->detect($image,'BASE64',$options);
//输出百度人脸识别反馈的结果。这行代码可忽略。
    echo json_encode($ret,JSON_UNESCAPED_UNICODE); 
//根据刚才百度人脸识别返回的结果判定
    if($ret['error_code']==0){   //有人脸
        $result = $ret['result'];        
        $face_num = $result['face_num'];  //人脸数
        $opp = array();
        $opp['user_info'] ='2';  //附加信息。以后会用到,我这里2为数据库需要的用户组
        if(1==$face_num){    //人脸数目为1才执行
            $face_probability = $result['face_list'][0]['face_probability'];
            if(1==$face_probability){    //可靠性为1,判断人脸真实性
              $client->addUser($image,'BASE64','stu',$userId,$opp);
                echo "$file";
            }else{
                die('可靠性为:' . $face_probability);
            }
        }else{
            die('人脸数量大于1');
        }
    }
}
}
//最后调动类里的方法
$post =new post(); 
echo $post->facevalid(); 
 ?>

B.PHP(负责数据库管理)

//检测用户名是否重复
elseif($type == "checkname"){
	$post_name = $_POST["name"];  //用户名
	$con = mysqli_connect("xxxx","xxxx","xxxx") or die("数据库连接失败");//连接数据库
	mysqli_query($con,"set names utf8");
	mysqli_select_db($con,"stu") or die("数据库选择失败");
	$sql_search="SELECT name from user where name = '$_POST[name]'";
	$result_search = mysqli_query($con,$sql_search);
	$num_search = mysqli_num_rows($result_search);
	if ($num_search >=1){
		echo "1";}
}
//人脸注册
elseif($type == "resface"){
		$post_name = $_POST["name"];   //用户名
		$post_face = $_POST["vface"];  //照片本地地址
		$level = "2";   //用户组
		$con = mysqli_connect("xxxxx","xxxxx","xxxxxx") or die("数据库连接失败");//连接数据库
		mysqli_query($con,"set names utf8");
		mysqli_select_db($con,"stu") or die("数据库选择失败");
		$sql_insert="INSERT INTO user (id,name,level,vface) VALUES (null,'$post_name','$level','$post_face')";
		$result_insert = mysqli_query($con,$sql_insert);
		echo "注册成功";
}

微信小程序端
JS代码

Page({
  data: {
    nickName: "", //用户昵称
    src: "", //上传到服务器的照片路径
    msg: "", //服务器返回信息
    url: "", //注册成功后自动回到登录界面
    disabled: false, //注册按钮判断用户名是否重复显示状态
  },

//拍照
  takePhoto() {
    var that = this
    var user_id = that.data.nickName
    wx.chooseImage({
//只能使用摄像头上传一张照片。一点点防止作弊的方法吧
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['camera'],
      success(res) {
        wx.showLoading({
          title: '人脸上传中',
          mask: true  
        })
        //上传人脸进行注册
        var tempFilePaths = res.tempFilePaths
        //上传照片到服务器
        wx.uploadFile({
          url: 'https://www.ailaiyun.com/A.php',
          filePath: tempFilePaths[0],
          name: 'file',
        //携带的参数,输入框输入的用户名。方便在百度人脸库根据这个用户名建立相应的用户
          formData: {
            user_id: that.data.nickName
          },
          success(res) {
         //上传成功后隐藏loading窗口
            wx.hideLoading()
          //把服务器返回的图片本地地址保存到data里面,方便调用
             var msg = res.data
             that.setData({
               msg
             })
             console.log(that.data.msg)
          //判断上传成功后,把服务器端图片上传的本地地址保存的数据库,以此判断此用户是否绑定人脸注册
            if (res.statusCode == "200") {
              wx.request({
                url: 'https://www.ailaiyun.com/B.php',
                method: "post",
                header: {
                  "Content-Type": "application/x-www-form-urlencoded"
                },
                data: {
                //服务器端执行类型为resface的条件语句,加入图片服务器端地址到数据库
                  type: "resface",
                  name: that.data.nickName,
                  vface: that.data.msg
                },
                success(res) {
                },
              })
              wx.showToast({
                title: '人脸注册成功',
                icon: 'success',
              })
              setTimeout(function () {
             //这是延时返回到登陆窗口
                wx.switchTab({
                  url: '../index/index'
                })
              }, 3000)
            }
          }
        })
      }
    })
  },

  //获取用户信息
  bindGetUserInfo: function(e) {
    var that = this;
//获取输入框输入的名字并赋值。。。坑。。。。这里不能有空格,只能是字母、数字、下划线。否者百度人脸库无法识别就无法入库了
    this.setData({
      nickName: e.detail.value
    })
//查询数据库里是否已经有这个用户名
    wx.request({
      url: 'https://www.ailaiyun.com/B.php',
      method: "post",
      header: {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      data: {
//更具type判断应该在后端使用那条语句
        type: "checkname",
        name: that.data.nickName,
      },
      success(res) {
        console.log(res.data)
//后端返回查询到的数量
        if (res.data == 1) {
          wx.showToast({
            title: '用户已经存在',
            icon: 'success',
            duration: 4000
          })
//如果用户名已注册,设置按钮禁用
          that.setData({
            disabled: true
          })
        } else {
          wx.showToast({
            title: '用户名可以注册',
            icon: 'success',
          })
//如果用户名可使用,设置注册按钮可用
          that.setData({
            disabled: false
          })
        }
      }
    })
  },
})

WXML代码:

<!--pages/camera/camera.wxml-->
<view class='text-info'>
  <view class='title'>人脸注册须知</view>
  <view class='content-text'>用户名只能由数字、字母、下划线组成——不支持中文</view>
  <view class='content-text'>先输入用户名,再拍照注册哦!网络可能故障,如果不成功,请再试一下!</view>  
</view>
<!-- 需要使用 button 来授权登录 -->
<input bindinput="bindGetUserInfo" placeholder='请输入用户名' class='inputname' />
<!-- 拍照按钮 -->
<button type="warn" bindtap="takePhoto" class='btn' disabled='{{disabled}}'> 人脸注册 </button>

WXSS代码:(这里只是基本样式,待修改)

/* pages/res_face/res_face.wxss */
.btn{
  width: 80%;
  margin-top: 30rpx;
}
.inputname{
  background-color: rgb(228, 240, 186);
  border-radius: 15rpx;
  height: 70rpx;
  width: 80%;
  margin: 30rpx auto;
  text-align: center;
}
.text-info{
  display: flex;
  flex-direction: column;
  width: 90%;
  margin: 0 auto;
}
.title{
  font-size: 40rpx;
  font-weight: bolder;
  margin: 0 auto;
}
.content-text{
  color: red;
  margin: 20rpx auto;
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注