如何在不将 canvas 附加到页面的情况下使用 canvas 从视频中解析图像数据?
How to use canvas for parsing imageData from video without appending canvas to the page?
我有 Webcam
class,用于从网络摄像头捕获数据。 class 将数据流式传输到视频标签并将其绘制在 canvas 上,我还有 QRScanner
class,用于解析来自 imageData
的 QR 码canvas.
class Webcam {
constructor(videoTag, canvasTag) {
// using for real-time video capture
this.videoTag = videoTag;
// qr scanner parses imageData from this element
this.canvasTag = canvasTag;
// waiting for qr code here
this.captureArea = {
x: 100,
y: 60,
width: 120,
height: 120
}
// getting access to webcam
navigator.mediaDevices
.getUserMedia({
video: true
})
.then(stream => this.videoTag.srcObject = stream)
.catch(console.log);
}
capture() {
setInterval(() => {
let ctx = this.canvasTag.getContext('2d');
ctx.drawImage(this.videoTag, 0, 0, 320, 240);
// drawing capture area
ctx.strokeStyle = 'red';
// this arguments also should be passed into qr scanner
ctx.strokeRect(
this.captureArea.x,
this.captureArea.y,
this.captureArea.width,
this.captureArea.height
);
}, 100);
}
}
class QRScanner {
constructor(canvas, router, captureArea) {
this.canvas = canvas;
this.router = router;
this.captureArea = captureArea;
this.qrCode = null;
}
scan() {
setInterval(() => {
let imageData = this.canvas
.getContext('2d')
.getImageData(
this.captureArea.x,
this.captureArea.y,
this.captureArea.width,
this.captureArea.height
).data;
// parsing qr code from canvas
this.qrCode = jsQR(imageData, this.captureArea.width, this.captureArea.height);
if (this.qrCode) {
router.redirect(Router.pages.result, this.qrCode);
let resultPage = document.querySelector('#result .qr-code-data');
resultPage.innerHTML = this.qrCode.data;
}
}, 100);
}
}
<div id="scan">
<video id="video" width="320" height="240" autoplay title="Real-time video stream from webcam"></video>
<canvas id="preview" width="320" height="240" title="Capture area for QR code"></canvas>
</div>
这按预期工作,但是当我从页面中删除 canvas
元素并尝试使用临时 canvas(使用 document.createElement('canvas')
而不附加到页面)时 - 此解决方案不工作。是否可以使用临时 canvas
获取 video
imageData
而无需将此 canvas 附加到页面?
P.S。我正在使用 https://github.com/cozmo/jsQR
Canvas 元素在未明确设置时具有默认宽度和高度。由于您从未为您创建的 canvas 设置它们,因此它将默认为 300 x 150,至少 Chrome 可能与其他浏览器实现不同。
var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)
并且由于此默认大小与您尝试将 image/video 绘制到的大小不同,因此将进行一些裁剪,从而影响您的 QR 库正确读取图像。
只要设置你需要的宽度和高度就可以了
var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;
我有 Webcam
class,用于从网络摄像头捕获数据。 class 将数据流式传输到视频标签并将其绘制在 canvas 上,我还有 QRScanner
class,用于解析来自 imageData
的 QR 码canvas.
class Webcam {
constructor(videoTag, canvasTag) {
// using for real-time video capture
this.videoTag = videoTag;
// qr scanner parses imageData from this element
this.canvasTag = canvasTag;
// waiting for qr code here
this.captureArea = {
x: 100,
y: 60,
width: 120,
height: 120
}
// getting access to webcam
navigator.mediaDevices
.getUserMedia({
video: true
})
.then(stream => this.videoTag.srcObject = stream)
.catch(console.log);
}
capture() {
setInterval(() => {
let ctx = this.canvasTag.getContext('2d');
ctx.drawImage(this.videoTag, 0, 0, 320, 240);
// drawing capture area
ctx.strokeStyle = 'red';
// this arguments also should be passed into qr scanner
ctx.strokeRect(
this.captureArea.x,
this.captureArea.y,
this.captureArea.width,
this.captureArea.height
);
}, 100);
}
}
class QRScanner {
constructor(canvas, router, captureArea) {
this.canvas = canvas;
this.router = router;
this.captureArea = captureArea;
this.qrCode = null;
}
scan() {
setInterval(() => {
let imageData = this.canvas
.getContext('2d')
.getImageData(
this.captureArea.x,
this.captureArea.y,
this.captureArea.width,
this.captureArea.height
).data;
// parsing qr code from canvas
this.qrCode = jsQR(imageData, this.captureArea.width, this.captureArea.height);
if (this.qrCode) {
router.redirect(Router.pages.result, this.qrCode);
let resultPage = document.querySelector('#result .qr-code-data');
resultPage.innerHTML = this.qrCode.data;
}
}, 100);
}
}
<div id="scan">
<video id="video" width="320" height="240" autoplay title="Real-time video stream from webcam"></video>
<canvas id="preview" width="320" height="240" title="Capture area for QR code"></canvas>
</div>
这按预期工作,但是当我从页面中删除 canvas
元素并尝试使用临时 canvas(使用 document.createElement('canvas')
而不附加到页面)时 - 此解决方案不工作。是否可以使用临时 canvas
获取 video
imageData
而无需将此 canvas 附加到页面?
P.S。我正在使用 https://github.com/cozmo/jsQR
Canvas 元素在未明确设置时具有默认宽度和高度。由于您从未为您创建的 canvas 设置它们,因此它将默认为 300 x 150,至少 Chrome 可能与其他浏览器实现不同。
var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)
并且由于此默认大小与您尝试将 image/video 绘制到的大小不同,因此将进行一些裁剪,从而影响您的 QR 库正确读取图像。
只要设置你需要的宽度和高度就可以了
var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;