H5扫描条形码
参考链接:https://www.npmjs.com/package/zbar.wasm
安装 zbar.wasm
npm i zbar.wasm
安装file-loader 解析 wasm文件
npm i file-loader
配置vue.config.js文件
chainWebpack(config) {
config.module
.rule('wasm')
.test(/\.bin$/)
.type('javascript/auto')
.use('file-loader')
.loader('file-loader')
.end()
}
使用 zbar.wasm扫码条形码
引入zbar.wasm
const { scanImageData } = require('zbar.wasm');
设置扫码时间
const SCAN_PROID_MS = 800;
根据可视化页面高度重置video高度
const handleResize = () => {
const width = document.documentElement.clientWidth;
const height = document.documentElement.clientHeight;
const videos = document.querySelector('video');
videos.style.width="100%"
videos.style.height="100%"
videos.style.objectFit="fill"
const canvas = document.querySelector('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
if (width / video.videoWidth < height / video.videoHeight) {
canvas.style.width = '100vw';
canvas.style.height = 'auto';
} else {
canvas.style.width = 'auto';
canvas.style.height = '100vh';
}
};
初始化
const init = async () => {
window.onresize = handleResize;
const mediaStream = await navigator.mediaDevices.getUserMedia({
audio: false,
video: {
facingMode: 'environment', //强制使用后置摄像头
//facingMode: "user" , //强制使用前置摄像头
width: { ideal: 1280 }, // 建议1280*720分辨率,分辨率大小跟扫描结果快慢有关系
height: { ideal: 720 }
}
});
const video = document.querySelector('video');
video.srcObject = mediaStream;
video.setAttribute('playsinline', '');
video.play();
await new Promise(r => {
video.onloadedmetadata = r;
});
handleResize();
};
const render = (symbols) => {
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const width = canvas.width;
const height = canvas.height;
ctx.clearRect(0, 0, width, height);
ctx.font = '20px serif';
ctx.strokeStyle = '#00ff00';
ctx.fillStyle = '#ff0000';
ctx.lineWidth = 6;
for (let i = 0; i < symbols.length; ++i) {
const sym = symbols[i];
const points = sym.points;
ctx.beginPath();
for (let j = 0; j < points.length; ++j) {
const {
x,
y
} = points[j];
if (j === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.closePath();
ctx.stroke();
ctx.fillText('#' + i, points[0].x, points[0].y - 10);
const video = document.querySelector('video');
video.load()
this.$emit('scans', sym.decode())
}
};
const scan = async () => {
const canvas = document.createElement('canvas');
const video = document.querySelector('video');
const width = video.videoWidth;
const height = video.videoHeight;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, width, height);
const imgData = ctx.getImageData(0, 0, width, height);
const res = await scanImageData(imgData);
render(res);
};
const sleep = ms => new Promise(r => {
setTimeout(r, ms)
});
const main = async () => {
try {
await init();
while (true) {
await scan();
await sleep(SCAN_PROID_MS);
}
} catch (err) {
}
};
调用
main()