You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jQuery人脸检测验证上传护照照片时出现getImageData错误

解决人脸检测插件在FileReader预览后报错的问题

问题根源

报错的核心原因是图片还没加载完成就触发了人脸检测:通过FileReader给img标签设置src后,图片加载是异步过程,此时图片的宽高还没被浏览器解析(width为0),插件调用getImageData自然会失败。另外原代码在页面初始化时就给空图片绑定了检测,后续上传新图后也没重新触发检测,逻辑上存在漏洞。

修复方案

  1. 移除页面初始化时的faceDetection绑定,改为在图片加载完成后再执行检测
  2. 给预览图片添加load事件监听,确保图片完全加载后再调用人脸检测
  3. 每次上传新图时,先清除之前的人脸标记(优化体验)

修改后的完整代码

HTML

<!DOCTYPE html>
<html>
<head>
    <title>Face Detection - LaravelCode</title>
    <script src="../Content/Scripts/jquery-3.6.0.js"></script>
    <script src="../Content/Scripts/jquery.facedetection/jquery.facedetection.min.js"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <input type="file" id="fp" />
        </div>
        <div class="row">
            <img id="previewImg" src="" alt="img">
            <br />
        </div>
    </div>
</body>
</html>

CSS

.picture-container {
    position: relative;
    width: 600px;
    height: auto;
    margin: 20px auto;
    border: 10px solid #fff;
    box-shadow: 0 5px 5px #000;
}

.picture {
    display: block;
    width: 100%;
    height: auto;
}

.face {
    position: absolute;
    border: 2px solid #FFF;
}

.row {
    margin: 20px
}

JavaScript

$(function () {
    $("#fp").change(function (e) {
        var ext = $('#fp').val().split('.').pop().toLowerCase();
        if ($.inArray(ext, ['gif', 'png', 'jpg', 'jpeg']) == -1) {
            $("#fp").val("");
            alert('invalid extension!');
            return;
        }
        const file = this.files[0];
        if (file) {
            let reader = new FileReader();
            reader.onload = function (event) {
                $("#previewImg").attr("src", event.target.result);
            };
            reader.readAsDataURL(file);
        }
        e.preventDefault();
    });

    // 监听预览图片加载完成事件,加载完成后执行人脸检测
    $("#previewImg").on('load', function() {
        // 清除之前的人脸标记
        $('.face').remove();
        
        // 执行人脸检测
        $(this).faceDetection({
            complete: function (faces) {
                if (faces.length > 0) {
                    alert("Valid");
                } else {
                    alert("Not Valid");
                }
                for (var i = 0; i < faces.length; i++) {
                    $('<div>', {
                        'class': 'face',
                        'css': {
                            'position': 'absolute',
                            'left': faces[i].x * faces[i].scaleX + 'px',
                            'top': faces[i].y * faces[i].scaleY + 'px',
                            'width': faces[i].width * faces[i].scaleX + 'px',
                            'height': faces[i].height * faces[i].scaleY + 'px'
                        }
                    }).insertAfter(this);
                }
            },
            error: function (code, message) {
                alert('Error: ' + message);
            }
        });
    });
});

关键修改点

  • 把faceDetection的调用移到了图片的load事件回调里,确保图片完全加载后再执行检测
  • 添加了清除旧人脸标记的逻辑,避免多次上传后标记重叠
  • 修复了文件验证后的return逻辑,避免无效文件继续执行后续代码

内容的提问来源于stack exchange,提问作者PAVAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 07:24:20