技术拆解
getUserMedia
API:- 用于访问设备摄像头,获取视频流并在网页上实时显示。它是实现拍照和扫码功能的核心技术。
canvas
元素:- 用于捕捉和绘制摄像头的当前视频帧,以实现拍照功能。通过
canvas
可以将视频帧转换为静态图像。
- 用于捕捉和绘制摄像头的当前视频帧,以实现拍照功能。通过
jsQR
库:- 轻量级的 JavaScript 库,用于解析二维码。它能够从视频帧中提取二维码信息,实现扫码功能。
这些技术共同实现了前端拍照和扫码的核心功能,是开发类似应用的关键技术基础。
1. 设计前端页面的代码
<h2>调用摄像头拍照</h2>
<video id="video" autoplay></video>
<button id="snap">拍照</button>
<canvas id="canvas"></canvas>
<h2>扫码功能</h2>
<video id="qr-video" autoplay></video>
<p id="qr-result">二维码结果将在此显示...</p>
2. 获取节点、初始化摄像头的代码
// 获取 HTML 元素节点
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const snapButton = document.getElementById('snap');
const context = canvas.getContext('2d');
const qrVideo = document.getElementById('qr-video');
const qrResult = document.getElementById('qr-result');
初始化摄像头的代码
// 初始化摄像头,显示在视频元素中
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
video.srcObject = stream;
})
.catch(err => {
console.error("Error accessing the camera: ", err);
});
// 初始化扫码摄像头
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
.then(stream => {
qrVideo.srcObject = stream;
qrVideo.setAttribute('playsinline', true); // 兼容iOS
qrVideo.play();
requestAnimationFrame(scanQR);
})
.catch(err => {
console.error("Error accessing the camera for QR scanning: ", err);
});
扫码功能的代码
<script src="https://cdn.jsdelivr.net/npm/jsqr/dist/jsQR.js"></script>
扫码功能的代码
// 扫描二维码
function scanQR() {
if (qrVideo.readyState === qrVideo.HAVE_ENOUGH_DATA) {
const qrCanvas = document.createElement('canvas');
const qrContext = qrCanvas.getContext('2d');
qrCanvas.height = qrVideo.videoHeight;
qrCanvas.width = qrVideo.videoWidth;
qrContext.drawImage(qrVideo, 0, 0, qrCanvas.width, qrCanvas.height);
const imageData = qrContext.getImageData(0, 0, qrCanvas.width, qrCanvas.height);
const code = jsQR(imageData.data, qrCanvas.width, qrCanvas.height);
if (code) {
qrResult.textContent = `QR Code detected: ${code.data}`;
} else {
qrResult.textContent = "未检测到二维码,请稍后再试...";
}
}
requestAnimationFrame(scanQR);
}
拍照功能的代码
// 拍照并将图像显示在 canvas 中
snapButton.addEventListener('click', () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
context.drawImage(video, 0, 0, canvas.width, canvas.height);
});
效果展示
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H5 调用摄像头拍照 & 扫码</title>
<style>
video, canvas {
width: 100%;
max-width: 500px;
margin: 10px 0;
}
</style>
</head>
<body>
<h2>调用摄像头拍照</h2>
<video id="video" autoplay></video>
<button id="snap">拍照</button>
<canvas id="canvas"></canvas>
<h2>扫码功能</h2>
<video id="qr-video" autoplay></video>
<p id="qr-result">二维码结果将在此显示...</p>
<script src="https://cdn.jsdelivr.net/npm/jsqr/dist/jsQR.js"></script>
<script>
// 拍照功能
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const snapButton = document.getElementById('snap');
const context = canvas.getContext('2d');
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
video.srcObject = stream;
})
.catch(err => {
console.error("Error accessing the camera: ", err);
});
snapButton.addEventListener('click', () => {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
context.drawImage(video, 0, 0, canvas.width, canvas.height);
});
// 扫码功能
const qrVideo = document.getElementById('qr-video');
const qrResult = document.getElementById('qr-result');
navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
.then(stream => {
qrVideo.srcObject = stream;
qrVideo.setAttribute('playsinline', true); // 兼容iOS
qrVideo.play();
requestAnimationFrame(scanQR);
})
.catch(err => {
console.error("Error accessing the camera for QR scanning: ", err);
});
function scanQR() {
if (qrVideo.readyState === qrVideo.HAVE_ENOUGH_DATA) {
const qrCanvas = document.createElement('canvas');
const qrContext = qrCanvas.getContext('2d');
qrCanvas.height = qrVideo.videoHeight;
qrCanvas.width = qrVideo.videoWidth;
qrContext.drawImage(qrVideo, 0, 0, qrCanvas.width, qrCanvas.height);
const imageData = qrContext.getImageData(0, 0, qrCanvas.width, qrCanvas.height);
const code = jsQR(imageData.data, qrCanvas.width, qrCanvas.height);
if (code) {
qrResult.textContent = `QR Code detected: ${code.data}`;
} else {
qrResult.textContent = "未检测到二维码,请稍后再试...";
}
}
requestAnimationFrame(scanQR);
}
</script>
</body>
</html>
Comments NOTHING