java人脸识别怎么写-------源码附上

1 首先在Face++注册一个自己的账号
https://console.faceplusplus.com.cn/dashboard

人脸

人脸(Face)在人脸识别技术中特指图像中发现的人脸,当对一张图片进行人脸检测时,会将检测到的人脸记录下来,包括人脸在图片中的位置,用一个系统标识face_token来表示。注意:对同一张图片进行多次人脸检测,对同一个人脸会得到不同的face_token。

人脸集合

人脸集合(FaceSet)是用来存储检测到人脸的存储对象。一个FaceSet内face_token是不重复的

人脸比对/人脸搜索

计算机检测到图片中一个人脸之后,通过人脸判断人身份的过程被称为人脸比对/人脸搜索。
人脸比对指采集新的人脸,与一个已知身份用户的人脸进行比对,判断新的人脸是否属于该已知身份用户。人脸比对需要调用Compare API。
人脸搜索是指采集用户新的人脸,在多个已知身份用户的人脸集合中进行搜索,找出新的人脸属于哪一个已知身份用户。
人脸搜索需要调用Search API。

创建API Key

要调用 API,需要先创建一个 API Key(API 密钥),它是使用 API 和 SDK 的凭证。注册验证成功后,您可以在欢迎页面点击“创建我的第一个应用”,一个免费API Key会被自动生成,您可以直接使用。(注:免费API key 可依据免费规则调用API,如果您希望使用付费版服务,请按下面步骤创建正式API Key。)
在这里插入图片描述
完成 API Key 创建之后,您可以在控制台看到自己的账户余额和API调用量的统计。
在这里插入图片描述
postman调用API接口
在这里插入图片描述

人脸检测

人脸检测的API文档

执行下述步骤以后,看返回的结果
在这里插入图片描述
通过对比API参数可以看到 响应字段的意思

人脸对比

API文档

在这里插入图片描述
传两张不一样的照片,再看看置信度
在这里插入图片描述

创建faceSet

API文档
产生了一个faceset集合
在这里插入图片描述

添加face到faceset

api文档
成功添加到人脸集合里
在这里插入图片描述

根据outer_id得到faceset

api文档

可以看到有一张人脸
在这里插入图片描述
继续往faceset添加一张图片可以检测到数量已经变为2
在这里插入图片描述

删除人脸

api文档
在这里插入图片描述
可以看到删除后数量已经减少了
在这里插入图片描述

人脸识别实现刷脸登录

录入人脸信息,通过人脸检测接口得到face_token,存入outer_id=travel_faceset的faceset中当用户在登录的时候,得到用户当前登录图片,然后用人脸比对接口用当前登录图片和之前在faceset中保存的人脸信息进行比对。
比对后的返回信息有我们设置的阈值(thresholds),可以根据自身的需求选择其中一个阈值,当相似度(confidence)高于这个阈值时就可以认为是同一个人,即可以登录成功,反之,不能登录成功。

本项目是基于springboot项目的 。所以接下来的配置是在我的一个已有的springboot项目上进行人脸登录的

需要在配置文件中添加

face:
  config:
    api-key: JtGRv7lXpLK3wkip5KKIdDaOOKe1J-Cx
    api-secret: 1zZ-eiAQiw7x-yG0gQ6ta0tmIB9GqLDg
    outer-id: faceset1

启动类中配置restTemplate

@SpringBootApplication
public class TravelApplication {
    
    
@Bean
public RestTemplate restTemplate() {
    
    
  return new RestTemplate();
}
public static void main(String[] args) {
    
    
  SpringApplication.run(TravelApplication.class, args);
}
}

下面就是DAO层的业务,和上边的postman里边的请求是一样的

DAO层

package com.xxq.mapper;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@ConfigurationProperties("face.config")
@Component
@Getter
@Setter
public class FaceDao {
    
    

    @Autowired
    private RestTemplate restTemplate;

    private String apiKey;
    private String apiSecret;
    private String outerId;

/**
 * 人脸检测
 * @param filePath
 * @return
 * /
 * */

    public DetectResponseEntity detect(String filePath) {
    
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 多部件表单体
        MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
       // ----------------- 表单 part  普通域
        multipartBodyBuilder.part("api_key", apiKey);
        multipartBodyBuilder.part("api_secret", apiSecret);
         // ----------------- 文件域 part
        // 从磁盘读取文件
        multipartBodyBuilder.part("image_file", new FileSystemResource(Paths.get(filePath)), MediaType.IMAGE_PNG);
       // build完整的消息体
        MultiValueMap<String, HttpEntity<?>> multipartBody =multipartBodyBuilder.build();
        ResponseEntity<DetectResponseEntity> responseEntity =
                restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/detect",
                        multipartBody, DetectResponseEntity.class);
        return responseEntity.getBody();
    }
    /**
     * 创建用于登录的人脸faseSet
     */
    public void faceSetCreate() {
    
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);//普通的表单请求
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        map.add("api_key", apiKey);
        map.add("api_secret", apiSecret);
        map.add("outer_id", outerId);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>
                (map, headers);
        restTemplate.postForEntity("https://apicn.faceplusplus.com/facepp/v3/faceset/create", request, String.class);
    }
    /**
     * 得到登录人脸FaceSet详细信息
     */
    public FaceSetResponseEntity getFaceSetDetail() {
    
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        map.add("api_key", apiKey);
        map.add("api_secret", apiSecret);
        map.add("outer_id", outerId);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>
                (map, headers);
        ResponseEntity<FaceSetResponseEntity> responseEntity =
                restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/faceset/getdetail", request,
                        FaceSetResponseEntity.class);
        return responseEntity.getBody();
    }
    /**
     * 添加faceToken到FaceSet
     * 人脸标识 faceTokens 组成的字符串,可以是一个或者多个,用逗号分隔。最多不超过5个
     face_token
     * @param faceTokens
     */
    public void addFaceToFaceSet(String faceTokens) {
    
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        map.add("api_key", apiKey);
        map.add("api_secret", apiSecret);
        map.add("outer_id", outerId);
        map.add("face_tokens", faceTokens);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<> (map, headers);
        restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/faceset/addface", request, String.class);
    }
    /**
     * 人脸比对
     * @param faceToken1
     * @param faceToken2
     * @return
     */
    public boolean compareFace(String faceToken1, String faceToken2) {
    
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 多部件表单体
        MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
        // ----------------- 表单 part
        multipartBodyBuilder.part("api_key", apiKey);
        multipartBodyBuilder.part("api_secret", apiSecret);
        multipartBodyBuilder.part("face_token1", faceToken1);
        multipartBodyBuilder.part("face_token2", faceToken2);
        // ----------------- 文件 part
         // 从磁盘读取文件
        //multipartBodyBuilder.part("image_file", new FileSystemResource(Paths.get(filePath)), MediaType.IMAGE_PNG);
        MultiValueMap<String, HttpEntity<?>> multipartBody =
                multipartBodyBuilder.build();
        ResponseEntity<CompareResponseEntity> responseEntity =
                restTemplate.postForEntity("https://api-cn.faceplusplus.com/facepp/v3/compare",
                        multipartBody, CompareResponseEntity.class);
        System.out.println(responseEntity);
        CompareResponseEntity e = responseEntity.getBody();
        if (e.getConfidence() >= e.getThresholds().e5) {
    
    
             return true;
        } else {
    
    
            return false;
        }
    }
    /**
     * 人脸比对返回实体类
     */
    @Data
    public static class CompareResponseEntity {
    
    
        private Double confidence;
        private ThresholdsResponseEntity thresholds;
    }
    /**
     * 人脸对比置信度阈值返回实体类
     */
    @Data
    public static class ThresholdsResponseEntity {
    
    
        @JsonProperty("1e-5")
        private Double e5;
    }
    /**
     * FaceSet返回实体类
     */
    @Data
    public static class FaceSetResponseEntity{
    
    
        private String faceset_token;
        private String outer_id;
        private Integer face_count;
        private List<String> face_tokens;
    }
    @Data
/**
 * 人脸检测返回数据实体类
 */
    public static class DetectResponseEntity {
    
    
        private String request_id;
        private Integer face_num;
        private List<FaceEntity> faces;
    }
    @Data
/**
 * 人脸实体类
 */
    public static class FaceEntity {
    
    
        private String face_token;
    }
}

测试类

package com.xxq.mapper;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)

public class FaceDaoTest {
    
    

    @Autowired
    private  FaceDao faceDao;
    @Test
   public void detect() {
    
    
       FaceDao.DetectResponseEntity entity=faceDao.detect("C:\\Users\\ly\\Desktop\\photo\\向.jpg");
       System.out.println(entity);
    }
    @Test
    public void getFaceSetDetail() {
    
    
        FaceDao.FaceSetResponseEntity e = faceDao.getFaceSetDetail();
        System.out.println(e);
    }
    // 这个方法只适用于没有outerID的faceset,有的话就创建不了,报错了。
    @Test
    public void createFaceSet() {
    
    
        faceDao.faceSetCreate();
    }
    @Test
    public void addFaceToFaceSet() {
    
    
        faceDao.addFaceToFaceSet("af1f0bd2054dfe2aa1ce06c3be7116fa");
    }
    @Test
    public void campareFace() {
    
    
        boolean b = faceDao.compareFace("04aeead26262cea830b63ec0c0a92507",
                "af1f0bd2054dfe2aa1ce06c3be7116fa");
        System.out.println(b);
    }

}

**

报错 java.lang.NoClassDefFoundError: org/reactivestreams/Publisher
添加下面的构件

**

<dependency>
  <groupId>org.reactivestreams</groupId>
  <artifactId>reactive-streams</artifactId>
  <version>1.0.3</version>
</dependency>

Service层

接口层

public interface FaceService {
    
    
    /*
    * 录入人脸
    * */
    public  void  addFace(String filePath);
    /*
    * 登录比对人脸
    * */
    public boolean loginByFace(String filePath);
}

实现层

package com.xxq.service.impl;

import com.xxq.service.FaceService;
import com.xxq.mapper.FaceDao;
import com.xxq.service.FaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;

@Service
public class FaceServiceImpl implements FaceService {
    
    
        @Autowired
        private FaceDao faceDao;
        @Override
        public void addFace(String filePath) {
    
    
            FaceDao.FaceSetResponseEntity fs = null;
            try {
    
    
                fs = faceDao.getFaceSetDetail();
            } catch (Exception e) {
    
    
                //单纯捕获一下,不做任何处理
            }
            if (fs == null) {
    
     //faceset不存在
                faceDao.faceSetCreate();
            }
            FaceDao.DetectResponseEntity dr = faceDao.detect(filePath); //检视人脸
            for (FaceDao.FaceEntity f : dr.getFaces()) {
    
    
                faceDao.addFaceToFaceSet(f.getFace_token());
            }
        }
        @Override
        public boolean loginByFace(String filePath) {
    
    
            boolean result = false;
            FaceDao.FaceSetResponseEntity fs = null;
            try {
    
    
                fs = faceDao.getFaceSetDetail();
            } catch (Exception e) {
    
    
            }
            if (fs == null) {
    
     //faceset不存在
                faceDao.faceSetCreate();
                fs = faceDao.getFaceSetDetail();
            }
            FaceDao.DetectResponseEntity dr = faceDao.detect(filePath); //检视人脸
            String ft1 = null;
            if (dr.getFace_num() >=1) {
    
    
                ft1 = dr.getFaces().get(0).getFace_token();
            } else {
    
    
                return false;
            }
            for (String ft2: fs.getFace_tokens()) {
    
    
                if (faceDao.compareFace(ft1, ft2)) {
    
    
                    result = true;
                }
            }
            new File(filePath).delete(); //删除登录人脸,节省服务器资源
            return result;
        }
    }



Controller层

package com.xxq.controller;
import com.xxq.service.FaceService;
import com.xxq.util.ImageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;

@Controller
@RequestMapping("/admin/face")
public class FaceController {
    
    
    @Autowired
    private FaceService faceService;
    /**
     * 调到录入人脸页面
     * @return
     */
    @RequestMapping("/toinput")
    public String toInput() {
    
    
        return "/face/input";
    }
    @RequestMapping("/tologin")
    public String toLogin() {
    
    
        return "/face/login";
    }
    /**
     * 录入人脸
     * @param imgData
     * @param request
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/upload")
    public ResponseEntity doAdd(@RequestParam("imgData") String imgData,
                                HttpServletRequest request) throws IOException {
    
    
        String savePath = request.getServletContext().getRealPath("img/face/");
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") +
                ".png";
        System.out.println(savePath);
        ImageUtils.generateImage(imgData.substring(22), savePath, fileName);
        faceService.addFace(savePath + fileName);
        return ResponseEntity.ok("{\"success\": \"true\"}");
    }
    /**
     * 人脸识别登录
     * @param imgData
     * @param request
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/login")
    public ResponseEntity login(@RequestParam("imgData") String imgData,
                                HttpServletRequest request) throws IOException {
    
    
        String savePath =
                request.getServletContext().getRealPath("img/face/login/");
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") +".png";
        System.out.println(savePath);
        ImageUtils.generateImage(imgData.substring(22), savePath, fileName);
        boolean b = faceService.loginByFace(savePath + fileName);
        if (b) {
    
    
            System.out.println("登录成功");
            return ResponseEntity.ok("{\"success\": true}");
        } else {
    
    
            System.out.println("登录失败");
            return ResponseEntity.ok("{\"success\": false}");
        }
    }
}

工具类,进行BASE64转码的

package com.xxq.util;
import sun.misc.BASE64Decoder;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class ImageUtils {
    
    

    public static boolean generateImage(String imgStr, String filePath, String fileName) {
    
    
        try {
    
    
            if (imgStr == null) {
    
    
                return false;
            }
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] b = decoder.decodeBuffer(imgStr);
            File file = new File(filePath);
            if (!file.exists()) {
    
    
                file.mkdirs();
            }
            OutputStream out = new FileOutputStream(filePath+fileName);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
    
    
            return false;
        }
    }

}

前端页面:

在这里插入图片描述

input.jtml

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta charset="utf-8"/>
    <title>用户管理</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>

    <!-- bootstrap & fontawesome -->
    <link rel="stylesheet" href="/assets/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="/assets/font-awesome/4.5.0/css/font-awesome.min.css"/>

    <!-- page specific plugin styles -->

    <!-- text fonts -->
    <link rel="stylesheet" href="/assets/css/fonts.googleapis.com.css"/>

    <!-- ace styles -->
    <link rel="stylesheet" href="/assets/css/ace.min.css" class="ace-main-stylesheet" id="main-ace-style"/>

    <!--[if lte IE 9]>
    <link rel="stylesheet" href="/assets/css/ace-part2.min.css" class="ace-main-stylesheet"/>
    <![endif]-->
    <link rel="stylesheet" href="/assets/css/ace-skins.min.css"/>
    <link rel="stylesheet" href="/assets/css/ace-rtl.min.css"/>

    <!--[if lte IE 9]>
    <link rel="stylesheet" href="/assets/css/ace-ie.min.css"/>
    <![endif]-->

    <!-- inline styles related to this page -->

    <!-- ace settings handler -->
    <script src="/assets/js/ace-extra.min.js"></script>

    <!-- HTML5shiv and Respond.js for IE8 to support HTML5 elements and media queries -->

    <!--[if lte IE 8]>
    <script src="/assets/js/html5shiv.min.js"></script>
    <script src="/assets/js/respond.min.js"></script>
    <![endif]-->

    <!--[if !IE]> -->
    <script src="/assets/js/jquery-2.1.4.min.js"></script>

    <!-- <![endif]-->

    <!--[if IE]>
    <script src="/assets/js/jquery-1.11.3.min.js"></script>
    <![endif]-->
    <script src="/assets/js/bootstrap.min.js"></script>

    <!-- page specific plugin scripts -->
    <script src="/assets/js/jquery.dataTables.min.js"></script>
    <script src="/assets/js/jquery.dataTables.bootstrap.min.js"></script>
    <script src="/assets/js/dataTables.buttons.min.js"></script>
    <script src="/assets/js/buttons.flash.min.js"></script>
    <script src="/assets/js/buttons.html5.min.js"></script>
    <script src="/assets/js/buttons.print.min.js"></script>
    <script src="/assets/js/buttons.colVis.min.js"></script>
    <script src="/assets/js/dataTables.select.min.js"></script>

    <!-- ace scripts -->
    <script src="/assets/js/ace-elements.min.js"></script>
    <script src="/assets/js/ace.min.js"></script>

</head>

<body class="no-skin">

<div th:replace="header :: navbar"></div>

<div class="main-container ace-save-state" id="main-container">
    <script type="text/javascript">
        try {
      
      
            ace.settings.loadState('main-container')
        } catch (e) {
      
      
        }
    </script>

    <div th:replace="left :: sidebar"></div>

    <div class="main-content">
        <div class="main-content-inner">
            <div class="breadcrumbs ace-save-state" id="breadcrumbs">
                <ul class="breadcrumb">
                    <li>
                        <i class="ace-icon fa fa-home home-icon"></i>
                        <a href="#">首页</a>
                    </li>
                    <li>
                        <a href="#">用户</a>
                    </li>
                    <li class="active">用户管理</li>
                </ul><!-- /.breadcrumb -->

            </div>

            <div class="page-content">

                <div style="padding: 10px;">
                    <tr>
                        <td colspan="2">
                            <button class="btn btn-sm btn-default" onclick="openMedia()">开启摄像头</button>
                            <button class="btn btn-sm btn-default" onclick="closeMedia()">关闭摄像头</button>
                            <button class="btn btn-sm btn-default" onclick="takePhoto()">录入人脸/button>
                        </td>
                    </tr>
                    <table>
                        <tr>
                            <td>
                                <video id="video" width="500px" height="500px" autoplay="autoplay"></video>
                                <canvas id="canvas" width="500px" height="500px" style="display: none"></canvas>
                            </td>
                            <td>
                                <img id="imgTag" src="" alt="..." width="500px" height="500px"><br>
                            </td>
                        </tr>
                    </table>

                    <script>
                        let mediaStreamTrack=null; // 视频对象(全局)
                        let video ;
                        function openMedia() {
      
      
                            let constraints = {
      
      
                                video: {
      
       width: 500, height: 500 },
                                audio: false
                            };
                            //获得video摄像头
                            video = document.getElementById('video');
                            let promise = navigator.mediaDevices.getUserMedia(constraints);
                            promise.then((mediaStream) => {
      
      
                                // mediaStreamTrack = typeof mediaStream.stop === 'function' ? mediaStream : mediaStream.getTracks()[1];
                                mediaStreamTrack=mediaStream.getVideoTracks()
                                video.srcObject = mediaStream;
                                video.play();
                            });
                        }

                        // 拍照
                        function takePhoto() {
      
      
                            //获得Canvas对象
                            let video = document.getElementById('video');
                            let canvas = document.getElementById('canvas');
                            let ctx = canvas.getContext('2d');
                            ctx.drawImage(video, 0, 0, 500, 500);


                            // toDataURL  ---  可传入'image/png'---默认, 'image/jpeg'
                            let img = document.getElementById('canvas').toDataURL();
                            // 这里的img就是得到的图片
                            console.log('img-----', img);
                            document.getElementById('imgTag').src=img;
                            //上传
                            $.ajax({
      
      
                                url:"/admin/face/upload",
                                type:"POST",
                                data:{
      
      "imgData":img},
                                success:function(data){
      
      
                                    alert("录入成功")
                                }
                                ,error:function(){
      
      
                                    alert("录入失败")
                                }
                            });

                        }

                        // 关闭摄像头
                        function closeMedia() {
      
      
                            let stream = document.getElementById('video').srcObject;
                            let tracks = stream.getTracks();

                            tracks.forEach(function(track) {
      
      
                                track.stop();
                            });

                            document.getElementById('video').srcObject = null;
                        }
                    </script>
                </div>

            </div><!-- /.page-content -->
        </div>
    </div><!-- /.main-content -->

</div><!-- /.main-container -->

</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
    <meta charset="utf-8"/>
    <title>用户管理</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>

    <!-- bootstrap & fontawesome -->
    <link rel="stylesheet" href="/assets/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="/assets/font-awesome/4.5.0/css/font-awesome.min.css"/>

    <!-- page specific plugin styles -->

    <!-- text fonts -->
    <link rel="stylesheet" href="/assets/css/fonts.googleapis.com.css"/>

    <!-- ace styles -->
    <link rel="stylesheet" href="/assets/css/ace.min.css" class="ace-main-stylesheet" id="main-ace-style"/>

    <!--[if lte IE 9]>
    <link rel="stylesheet" href="/assets/css/ace-part2.min.css" class="ace-main-stylesheet"/>
    <![endif]-->
    <link rel="stylesheet" href="/assets/css/ace-skins.min.css"/>
    <link rel="stylesheet" href="/assets/css/ace-rtl.min.css"/>

    <!--[if lte IE 9]>
    <link rel="stylesheet" href="/assets/css/ace-ie.min.css"/>
    <![endif]-->

    <!-- inline styles related to this page -->

    <!-- ace settings handler -->
    <script src="/assets/js/ace-extra.min.js"></script>

    <!-- HTML5shiv and Respond.js for IE8 to support HTML5 elements and media queries -->

    <!--[if lte IE 8]>
    <script src="/assets/js/html5shiv.min.js"></script>
    <script src="/assets/js/respond.min.js"></script>
    <![endif]-->

    <!--[if !IE]> -->
    <script src="/assets/js/jquery-2.1.4.min.js"></script>

    <!-- <![endif]-->

    <!--[if IE]>
    <script src="/assets/js/jquery-1.11.3.min.js"></script>
    <![endif]-->
    <script src="/assets/js/bootstrap.min.js"></script>

    <!-- page specific plugin scripts -->
    <script src="/assets/js/jquery.dataTables.min.js"></script>
    <script src="/assets/js/jquery.dataTables.bootstrap.min.js"></script>
    <script src="/assets/js/dataTables.buttons.min.js"></script>
    <script src="/assets/js/buttons.flash.min.js"></script>
    <script src="/assets/js/buttons.html5.min.js"></script>
    <script src="/assets/js/buttons.print.min.js"></script>
    <script src="/assets/js/buttons.colVis.min.js"></script>
    <script src="/assets/js/dataTables.select.min.js"></script>

    <!-- ace scripts -->
    <script src="/assets/js/ace-elements.min.js"></script>
    <script src="/assets/js/ace.min.js"></script>

</head>

<body class="no-skin">

<div class="main-container ace-save-state" id="main-container">

    <div class="main-content">
        <div class="main-content-inner">

            <div class="page-content">

                <div style="padding: 10px;">
                    <tr>
                        <td colspan="2">
                            <button class="btn btn-sm btn-default" onclick="openMedia()">开启摄像头</button>
                            <button class="btn btn-sm btn-default" onclick="closeMedia()">关闭摄像头</button>
                            <button class="btn btn-sm btn-default" onclick="takePhoto()">登录</button>
                        </td>
                    </tr>
                    <table>
                        <tr>
                            <td>
                                <video id="video" width="500px" height="500px" autoplay="autoplay"></video>
                                <canvas id="canvas" width="500px" height="500px" style="display: none"></canvas>
                            </td>
                            <td>
                                <img id="imgTag" src="" alt="..." width="500px" height="500px"><br>
                            </td>
                        </tr>
                    </table>

                    <script>
                        let mediaStreamTrack=null; // 视频对象(全局)
                        let video ;
                        function openMedia() {
      
      
                            let constraints = {
      
      
                                video: {
      
       width: 500, height: 500 },
                                audio: false
                            };
                            //获得video摄像头
                            video = document.getElementById('video');
                            let promise = navigator.mediaDevices.getUserMedia(constraints);
                            promise.then((mediaStream) => {
      
      
                                // mediaStreamTrack = typeof mediaStream.stop === 'function' ? mediaStream : mediaStream.getTracks()[1];
                                mediaStreamTrack=mediaStream.getVideoTracks()
                                video.srcObject = mediaStream;
                                video.play();
                            });
                        }

                        // 拍照
                        function takePhoto() {
      
      
                            //获得Canvas对象
                            let video = document.getElementById('video');
                            let canvas = document.getElementById('canvas');
                            let ctx = canvas.getContext('2d');
                            ctx.drawImage(video, 0, 0, 500, 500);


                            // toDataURL  ---  可传入'image/png'---默认, 'image/jpeg'
                            let img = document.getElementById('canvas').toDataURL();
                            // 这里的img就是得到的图片
                            console.log('img-----', img);
                            document.getElementById('imgTag').src=img;
                            //上传
                            $.ajax({
      
      
                                url:"/admin/face/login",
                                type:"POST",
                                data:{
      
      "imgData":img},
                                dataType: "json",
                                success:function(data){
      
      
                                    var b = data.success;
                                    alert(b);
                                    if (b) {
      
      
                                        alert("登录成功");
                                    } else {
      
      
                                        alert("登录失败");
                                    }

                                }
                                ,error:function(){
      
      
                                    alert("登录失败")
                                }
                            });

                        }

                        // 关闭摄像头
                        function closeMedia() {
      
      
                            let stream = document.getElementById('video').srcObject;
                            let tracks = stream.getTracks();

                            tracks.forEach(function(track) {
      
      
                                track.stop();
                            });

                            document.getElementById('video').srcObject = null;
                        }
                    </script>
                </div>

            </div><!-- /.page-content -->
        </div>
    </div><!-- /.main-content -->

</div><!-- /.main-container -->

</body>
</html>

猜你喜欢

转载自blog.csdn.net/delete_bug/article/details/121187790