How to use canvas for parsing imageData from video without appending canvas to the page?












0














I have Webcam class, that uses for capturing data from webcam. This class streames data to video tag and also draw it on canvas., Also I have QRScanner class, that uses for parsing QR code from imageData of 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>


This works as expected, but when I removes canvas element from page and trying to use temporary canvas (using document.createElement('canvas') without appending to the page) - this solution do not work. Does it possible to using temporary canvas for getting video imageData without appending this canvas to the page?



P.S. I'm using https://github.com/cozmo/jsQR










share|improve this question




















  • 1




    Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
    – Patrick Evans
    Nov 11 at 21:57












  • @PatrickEvans this is typo! Thank you, I removed this from code.
    – Sergio Ivanuzzo
    Nov 11 at 22:03










  • @PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
    – Sergio Ivanuzzo
    Nov 11 at 22:07
















0














I have Webcam class, that uses for capturing data from webcam. This class streames data to video tag and also draw it on canvas., Also I have QRScanner class, that uses for parsing QR code from imageData of 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>


This works as expected, but when I removes canvas element from page and trying to use temporary canvas (using document.createElement('canvas') without appending to the page) - this solution do not work. Does it possible to using temporary canvas for getting video imageData without appending this canvas to the page?



P.S. I'm using https://github.com/cozmo/jsQR










share|improve this question




















  • 1




    Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
    – Patrick Evans
    Nov 11 at 21:57












  • @PatrickEvans this is typo! Thank you, I removed this from code.
    – Sergio Ivanuzzo
    Nov 11 at 22:03










  • @PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
    – Sergio Ivanuzzo
    Nov 11 at 22:07














0












0








0







I have Webcam class, that uses for capturing data from webcam. This class streames data to video tag and also draw it on canvas., Also I have QRScanner class, that uses for parsing QR code from imageData of 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>


This works as expected, but when I removes canvas element from page and trying to use temporary canvas (using document.createElement('canvas') without appending to the page) - this solution do not work. Does it possible to using temporary canvas for getting video imageData without appending this canvas to the page?



P.S. I'm using https://github.com/cozmo/jsQR










share|improve this question















I have Webcam class, that uses for capturing data from webcam. This class streames data to video tag and also draw it on canvas., Also I have QRScanner class, that uses for parsing QR code from imageData of 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>


This works as expected, but when I removes canvas element from page and trying to use temporary canvas (using document.createElement('canvas') without appending to the page) - this solution do not work. Does it possible to using temporary canvas for getting video imageData without appending this canvas to the page?



P.S. I'm using https://github.com/cozmo/jsQR







javascript canvas qr-code






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 22:03

























asked Nov 11 at 21:49









Sergio Ivanuzzo

1,03931137




1,03931137








  • 1




    Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
    – Patrick Evans
    Nov 11 at 21:57












  • @PatrickEvans this is typo! Thank you, I removed this from code.
    – Sergio Ivanuzzo
    Nov 11 at 22:03










  • @PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
    – Sergio Ivanuzzo
    Nov 11 at 22:07














  • 1




    Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
    – Patrick Evans
    Nov 11 at 21:57












  • @PatrickEvans this is typo! Thank you, I removed this from code.
    – Sergio Ivanuzzo
    Nov 11 at 22:03










  • @PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
    – Sergio Ivanuzzo
    Nov 11 at 22:07








1




1




Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
– Patrick Evans
Nov 11 at 21:57






Why are you doing ctx.drawImage(canvas, 0, 0, 320, 240); right after drawing the videoTag? Also canvas elements have a default width height when they aren't set, you never set those for you created canvas so it is going to default to 300 x 150 (at least that is what my chrome's default is). So your image is going to be cut off. Try setting those to what you need and try again
– Patrick Evans
Nov 11 at 21:57














@PatrickEvans this is typo! Thank you, I removed this from code.
– Sergio Ivanuzzo
Nov 11 at 22:03




@PatrickEvans this is typo! Thank you, I removed this from code.
– Sergio Ivanuzzo
Nov 11 at 22:03












@PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
– Sergio Ivanuzzo
Nov 11 at 22:07




@PatrickEvans I setted width and height to my temporary canvas and all works fine! Thanks a lot! If you add your comment as answer - I will accept it.
– Sergio Ivanuzzo
Nov 11 at 22:07












1 Answer
1






active

oldest

votes


















1














Canvas elements have a default width height when they aren't explicitly set. Since you never set those for you created canvas it is going to default to 300 x 150, at least for Chrome might be different for other browsers implementations.






var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





And since this default size is different than the size that you are trying to draw the image/video to there is going to be some cropping going on and therefore effecting your QR library from properly reading the image.



Just set the width and height to what you need



var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;





share|improve this answer





















  • 300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
    – Kaiido
    Nov 11 at 23:34











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253593%2fhow-to-use-canvas-for-parsing-imagedata-from-video-without-appending-canvas-to-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Canvas elements have a default width height when they aren't explicitly set. Since you never set those for you created canvas it is going to default to 300 x 150, at least for Chrome might be different for other browsers implementations.






var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





And since this default size is different than the size that you are trying to draw the image/video to there is going to be some cropping going on and therefore effecting your QR library from properly reading the image.



Just set the width and height to what you need



var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;





share|improve this answer





















  • 300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
    – Kaiido
    Nov 11 at 23:34
















1














Canvas elements have a default width height when they aren't explicitly set. Since you never set those for you created canvas it is going to default to 300 x 150, at least for Chrome might be different for other browsers implementations.






var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





And since this default size is different than the size that you are trying to draw the image/video to there is going to be some cropping going on and therefore effecting your QR library from properly reading the image.



Just set the width and height to what you need



var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;





share|improve this answer





















  • 300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
    – Kaiido
    Nov 11 at 23:34














1












1








1






Canvas elements have a default width height when they aren't explicitly set. Since you never set those for you created canvas it is going to default to 300 x 150, at least for Chrome might be different for other browsers implementations.






var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





And since this default size is different than the size that you are trying to draw the image/video to there is going to be some cropping going on and therefore effecting your QR library from properly reading the image.



Just set the width and height to what you need



var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;





share|improve this answer












Canvas elements have a default width height when they aren't explicitly set. Since you never set those for you created canvas it is going to default to 300 x 150, at least for Chrome might be different for other browsers implementations.






var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





And since this default size is different than the size that you are trying to draw the image/video to there is going to be some cropping going on and therefore effecting your QR library from properly reading the image.



Just set the width and height to what you need



var canvas = document.createElement('canvas')
canvas.width = 320;
canvas.height = 240;





var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)





var canvas = document.createElement("canvas");
console.log(canvas.width,canvas.height)






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 11 at 22:11









Patrick Evans

31.8k54470




31.8k54470












  • 300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
    – Kaiido
    Nov 11 at 23:34


















  • 300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
    – Kaiido
    Nov 11 at 23:34
















300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
– Kaiido
Nov 11 at 23:34




300×150 is per specs. All browsers will use these values as default. And don't use hard-coded values, moreover when dealing with a webcam stream, each user will have a different device outputting a video of different quality. Use videoElement's videoWidth and videoHeight instead.
– Kaiido
Nov 11 at 23:34


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253593%2fhow-to-use-canvas-for-parsing-imagedata-from-video-without-appending-canvas-to-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Full-time equivalent

さくらももこ

13 indicted, 8 arrested in Calif. drug cartel investigation