uni-app基于百度人脸识别web实现人脸录入含活体检测

1、uni-app基于webview本地引入html文件

<template>
    <view>
        <web-view :src="url" @message="getMessage"></web-view>
    </view>
</template>

<script>
    
    export default {
        data() {
            return {
                url: '/hybrid/html/web/local.html#' // 
            }
        },
        methods: {
                        // html回调函数
            async getMessage(e) {
                // 处理人脸头像
                console.info(e.detail.data[0].photo)
                、、、
            }

        }
    }
</script>

<style>

</style>

2、html部分,上全部代码,可复制代码直接浏览器预览效果。活体检测部分,只做了微笑检测,可以根据需要进行调整。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
            content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
        <title>人脸录入</title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
            }

            html,
            body {
                height: 100%;
            }

            .flex {
                display: flex;
            }

            .flex-row {
                flex-direction: row;
                justify-content: space-around;
                align-items: center;
            }

            .flex-column {
                flex-direction: column;
                justify-content: flex-start;
                align-items: center;
            }

            body {
                overflow: auto;
            }

            .wrap {
                width: 100%;
            }

            .wrap .reference {
                position: relative;
                padding: 10px;
                background-color: rgba(255, 255, 255, 0);
            }

            .wrap .reference img.face {
                display: block;
                width: 350px;
                height: auto;
                border-radius: 10px;
            }

            .wrap .reference img.toggle {
                position: absolute;
                right: 10px;
                top: 10px;
                width: 50px;
                height: 50px;
            }

            .wrap .scan video {
                background-color: rgba(0, 0, 0, .8);
                border-radius: 10px;
            }

            .wrap .control {
                justify-content: space-around;
                height: 456px;
                padding: 0 20px;
            }

            .wrap .control p {
                width: 160px;
                height: 60px;
                background-color: #f9f9f9;
                text-align: center;
                line-height: 60px;
                color: #ffffff;
                font-size: 24px;
                border-radius: 8px;
                cursor: pointer;
                transition: .5s;
            }

            .wrap .scan {
                position: relative;
                overflow: hidden;
            }

            .wrap .scan .strainer {
                position: absolute;
                top: 10px;
                width: 350px;
                z-index: 998;
                height: 3px;
            }

            .wrap .scan .strainer1 {
                position: absolute;
                top: 10px;
                width: 350px;
                z-index: 999;
                height: 3px;
            }

            .wrap .scan .capture {
                width: 350px;
                height: 350px;
            }

            .wrap .scan .strainer.on {
                background: linear-gradient(to left, transparent, #0bffb2, transparent);
                animation: scan 1s linear infinite;
            }

            .bg,
            .pane {
                width: 260px;
                height: 260px;
                margin: 40px auto;
                overflow: hidden;
                /* 隐藏显示区域外的内容*/
            }

            .bg {
                position: relative;
                /* background: url(images/rllr_bg.png) center center no-repeat; */
                /* border: 1px solid #b0f9e4; */
                background-size: 100% 100%;
            }

            .front {
                position: absolute;
                top: 0;
                width: 100%;
                height: 68%;
                /* background: url(images/rllr_bg.png) center center no-repeat; */
                background-size: 100% 100%;
                z-index: 9999;
            }

            .front-msg {
                position: relative;
                top: -50px;
                color: #95F9FC;
                font-size: 30px;
                width: 100%;
                height: 30px;
                text-align: center;
            }

            .btn {
                position: relative;
                top: 70px;
                border-radius: 25px;
                width: 80%;
                height: 50px;
                background: linear-gradient(-35deg, #398EF6, #3974F6);
                font-size: 18px;
            }

            .pane {
                position: absolute;
                z-index: -1;
                background: url(images/4.png) center center no-repeat;
                background-size: 100% 100%;
                animation: move 1.5s ease-in-out infinite;
                -webkit-animation: move 1.5s ease-in-out infinite;
            }

            @keyframes move {
                from {
                    top: -260px
                }

                /*网格移动到显示区域的外面*/
                to {
                    top: 0
                }
            }

            -webkit-@keyframes move {
                from {
                    top: -260px
                }

                to {
                    top: 0
                }
            }

            @keyframes scan {
                0% {
                    top: 10px;
                }

                50% {
                    top: 456px;
                }

                100% {
                    top: 10px;
                }
            }

            .btn {
                display: block;
                margin: 20px auto;
                padding: 5px;
                background-color: #007aff;
                border: none;
                color: #ffffff;
            }

            .btn::focus {
                border: none !important;
            }

            video {
                transform: rotateY(180deg);
                -webkit-transform: rotateY(180deg);
                /* Safari 和 Chrome */
                -moz-transform: rotateY(180deg);
            }
        </style>
        <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
        <!--  <script type="text/javascript" src="js/vconsole.min.js"></script> -->
        <script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.1.js">
        </script>
    </head>
    <body style="background-color: #FFFFFF">
        <div class="title flex flex-column">
            <div style="width: 1px;height: 90px;"></div>
            <!--<textarea id="base64" class="title" style="width: 80%"></textarea>-->
        </div>
        <div class="wrap flex flex-row">
            <div class="control flex flex-column" style="display: none;">
                <p class="open">开启摄像头</p>
                <p class="recognition">显示到Canvas</p>
                <p class="close">关闭摄像头</p>
            </div>
            <div class="scan reference">

                <div class="strainer1">
                    <div class="bg">
                        <div class="pane"></div>
                    </div>
                </div>
                <video id="video" poster="images/2.png" class="capture" width="350" height="350" src=""
                    muted="true"></video>

            </div>

        </div>
        <div class="front">
            <img src="images/rllr_bg.png" width="100%" />
            <div class="front-msg" id="message">
            </div>
        </div>
        <button class="btn" type="button" onclick="goBackPage()">确认</button>
        <div class="title flex flex-column" dislpay="none">
            <!-- <button display="none" class="btn" type="button" id="postMessage">postMessage</button> -->
            <canvas style="display:none;" id="canvas" width="350" height="350"></canvas>
        </div>
        <script type="text/javascript">
            var buffer;
            var control = document.querySelector(".control");
            var video = document.getElementById('video');
            var canvas = document.getElementById('canvas');
            var message = document.getElementById('message');
            var context = canvas.getContext('2d');
            var count = 0,
                smile = false,
                eyeStatus = false,
                yaw = 0,
                successFace = false;

            var your_client_id = '替换成你的';
            var your_client_secret = '替换成你的';

            function closeCamera() {
                try {
                    buffer && buffer.getTracks()[1].stop(); //关闭摄像头
                } catch (e) {
                    //TODO handle the exception
                    return;
                }

            }

            (function() {
                window.addEventListener("DOMContentLoaded", function() {
                    // Grab elements, create settings, etc.
                    var mediaConfig = {
                        video: true
                    };
                    var errBack = function(e) {
                        console.log('An error has occurred!', e)
                    };
                    // Put video listeners into place
                    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                        console.log("navigator.mediaDevices");
                        navigator.mediaDevices.getUserMedia(mediaConfig).then(function(stream) {
                            // video.src = window.URL.createObjectURL(stream);
                            video.srcObject = stream;
                            video.play();
                            buffer = stream;
                        });
                    }
                    /* Legacy code below! */
                    else if (navigator.getUserMedia) { // Standard
                        navigator.getUserMedia(mediaConfig, function(stream) {
                            video.src = stream;
                            video.play();
                            buffer = stream;
                        }, errBack);
                    } else if (navigator.mozGetUserMedia) { // Mozilla-prefixed
                        navigator.mozGetUserMedia(mediaConfig, function(stream) {
                            video.src = window.URL.createObjectURL(stream);
                            video.play();
                            buffer = stream;
                        }, errBack);
                    } else if (navigator.msGetUserMedia) { // Mozilla-prefixed
                        navigator.msGetUserMedia(mediaConfig, function(stream) {
                            video.src = window.URL.createObjectURL(stream);
                            video.play();
                            buffer = stream;
                        }, errBack);
                    } else if (navigator.webkitGetUserMedia) { // WebKit-prefixed
                        navigator.webkitGetUserMedia(mediaConfig, function(stream) {
                            video.src = window.webkitURL.createObjectURL(stream);
                            video.play();
                            buffer = stream;
                        }, errBack);
                    }
                }, false);
                document.addEventListener('UniAppJSBridgeReady', function() {
                    //获取access_token
                    var baiduAccessTokenApi =
                        `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${your_client_id}&client_secret=${your_client_secret}`;
                    $.ajax({
                        url: baiduAccessTokenApi,
                        method: 'GET',
                        dataType: 'json',
                        success(res) {
                            var access_token = res.access_token;
                            matchFace(access_token);
                        },
                        complete() {
                            count++;
                            if (successFace || count > 30) {
                                closeCamera();
                                uni.reLaunch({
                                    url: '/pages/newMain/newMain?cheakFace=' + successFace
                                })
                            }
                        }
                    })

                    function matchFace(access_token) {
                        var baiduApi = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' +
                            access_token;
                        send();

                        function send() {
                            $.ajax({
                                url: baiduApi,
                                contentType: "application/json",
                                method: 'POST',
                                data: JSON.stringify({
                                    "image": "" + getImage(),
                                    "image_type": "BASE64",
                                    "face_type": "LIVE",
                                    "quality_control": "LOW",
                                    "liveness_control": "NORMAL",
                                    "face_field": "expression"
                                }),
                                dataType: 'json',
                                timeout: 7000,
                                success(data) {
                                    if (data.error_code == 0 && data.result.face_list[0].face_probability ==1) {
                                        successFace = true
                                        // 活体检测部分, 这里做了微笑检测,可以根据需求更改
                                        smile = data.result.face_list[0].expression.type == 'smile'
                                        message.innerHTML = '检测到人脸'
                                    } else if (!successFace) {
                                        send()
                                        successFace = false
                                        message.innerHTML = '未检测到人脸'
                                    }
                                    if (smile) {
                                        message.innerHTML = '人脸采集完成'
                                        video.pause()
                                    } else if (successFace) {
                                        send()
                                        message.innerHTML = '请保持微笑'
                                    }

                                },
                                fail() {
                                    send();
                                }
                            })
                        }
                    }
                });
            })();

            function goBackPage() {
                if (successFace && smile) {
                    closeCamera();
                    uni.postMessage({
                        data: {
                            photo: getImage()
                        }
                    });
                }
            }

            function getImage() {
                context.drawImage(video, 0, 0, 320, 320);
                // 把画布的内容转换为base64编码格式的图片
                var data = canvas.toDataURL('image/png', 1); //1表示质量(无损压缩)
                return data.replace('data:image/png;base64,', '');
            }
        </script>
    </body>
</html>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容