前端js调用摄像头识别二维码信息
前端js调用摄像头后并使用已经编写好的Wasm模块库,在网页上实现实时获取摄像头的二维码信息,不需要使用后端识别或接口.
·
让网页调用摄像头和识别二维码信息是两个功能
网页调用摄像头
js调用摄像头可以使用MediaDevices.getUserMedia API,这个API在绝大部分现代浏览器中都支持,它的功能是获取摄像头的视频流数据,所以你还需要video标签配合播放视频,这样实现在网页上实时显示摄像头内容.
如果你的浏览器太旧,不支持MediaDevices.getUserMedia API,可以试试navigator.getUserMedia API
如果你想在电脑网页上调用摄像头,但是你的电脑又没有摄像头,你可以使用局域网摄像头,有很多可以实现的app.在手机上安装后,局域网访问或者在在电脑上安装指定的软件即可,注意请不要使用古早的usb电脑摄像头,视频清晰度太小的话,会导致识别不出来,并且这种摄像头一般没有自动对焦功能,只要一部手机就可以实现功能了.
识别图片中的二维码信息
有一项实验性质的API Barcode Detection API支持对于二维码和条形码的识别,但是限制较多,并且兼容度不高.所以我使用由作者:undecaf编写的barcode-detector-polyfill库,其原理是通过Wasm模块也就是WebAssembly运行C/C++来对图片进行精准的二维码识别.我实现的路径就是在页面上显示摄像头内容,然后循环对视频标签进行识别.
视频的宽度大小对于识别的精度与耗时有影响
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JS实时扫描二维码</title>
</head>
<body>
<p>摄像头图像</p>
<!-- 视频元素的autoplay="true" playsinline不可少 -->
<video id="videoEl" autoplay="true" playsinline></video>
<br />
<button onclick="identify()">开始识别条形码</button>
<p>识别状态:<span id="state">未开始</span></p>
<p>识别结果:<span id="number"></span></p>
<!-- 核心就是靠barcode-detector-polyfill实现,所以当你编写代码时,请前往https://github.com/undecaf/barcode-detector-polyfill获取最新版本 -->
<!-- 这个只是示例,国内访问这两个很慢还会跨域,所以推荐使用ES module安装到你的项目 npm install @undecaf/barcode-detector-polyfill -->
<!-- 官方npm链接https://www.npmjs.com/package/@undecaf/barcode-detector-polyfill -->
<script src="https://cdn.jsdelivr.net/npm/@undecaf/zbar-wasm@0.9.15/dist/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@undecaf/barcode-detector-polyfill@0.9.21/dist/index.js"></script>
<script>
// 检查并初始化BarcodeDetector API
(function initBarcodeDetector() {
try {
window["BarcodeDetector"].getSupportedFormats();
} catch {
window["BarcodeDetector"] =
barcodeDetectorPolyfill.BarcodeDetectorPolyfill;
}
})();
// 获取视频元素和识别器实例
const videoEl = document.getElementById("videoEl");
const detector = new window.BarcodeDetector();
let identificationTimer = null;
// 初始化摄像头并设置视频流
async function checkCamera() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: { facingMode: "environment" },
});
videoEl.srcObject = stream;
videoEl.play();
// 页面卸载时释放资源
window.addEventListener("beforeunload", () => {
stream.getTracks().forEach((track) => track.stop());
});
} catch (error) {
console.error("无法访问摄像头:", error);
}
}
// 识别条形码功能
async function identifyBarcodes() {
try {
const results = await detector.detect(videoEl);
if (results.length > 0) {
document.getElementById("number").innerText = results[0].rawValue;
stopIdentification();
}
} catch (error) {
console.error("条形码识别失败:", error);
}
}
// 开启或停止条形码识别
function identify(start = true) {
if (start) {
document.getElementById("state").innerText = "识别中...";
identificationTimer = setInterval(identifyBarcodes, 500);
} else {
stopIdentification();
document.getElementById("state").innerText = "结束识别";
}
}
// 停止条形码识别并清除定时器
function stopIdentification() {
if (identificationTimer) {
clearInterval(identificationTimer);
identificationTimer = null;
}
}
// 页面加载时初始化摄像头
window.onload = checkCamera;
</script>
</body>
</html>
更多推荐
所有评论(0)