I am getting video
from the user's camera, and displaying it on a 1:1 square. I then have a button that takes a picture and draws it to a 1:1 canvas, the issue is that it isn't drawn in the same location on the canvas. How can I achieve this?
Here is a running example:
/
Here is the HTML:
<!doctype html>
<html>
<head>
<title>Camera</title>
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: 'unsafe-inline'; style-src * 'unsafe-eval'; media-src 'self' blob:">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/camera.css">
</head>
<body>
<div class="container">
<div class="camera">
<video id="monitor" autoplay></video>
</div>
<canvas id="photo"></canvas>
<input type=button value="📷" onclick="snapshot()">
</div>
<script type="text/javascript" src="js/plugins/jquery.min.js"></script>
<script type="text/javascript" src="js/dist/pages/camera.js"></script>
</body>
</html>
Here is the CSS:
video {
width: 500px;
height: 500px;
object-fit: cover;
object-position: center;
}
.camera {
width: 500px;
height: 500px;
overflow: hidden;
}
Here is the TypeScript:
let canvas: HTMLCanvasElement;
let video: HTMLVideoElement;
$(window).on('load', async event => {
video = <HTMLVideoElement>document.getElementById('monitor');
canvas = <HTMLCanvasElement>document.getElementById('photo');
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
video.onloadedmetadata = () => {
canvas.width = 500;
canvas.height = 500;
}
});
function snapshot() {
canvas.getContext('2d').drawImage(video, 0, 0);
}
I am getting video
from the user's camera, and displaying it on a 1:1 square. I then have a button that takes a picture and draws it to a 1:1 canvas, the issue is that it isn't drawn in the same location on the canvas. How can I achieve this?
Here is a running example:
https://jsfiddle/90d3ar1m/
Here is the HTML:
<!doctype html>
<html>
<head>
<title>Camera</title>
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: https://ssl.gstatic. 'unsafe-inline'; style-src * 'unsafe-eval'; media-src 'self' blob:">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/camera.css">
</head>
<body>
<div class="container">
<div class="camera">
<video id="monitor" autoplay></video>
</div>
<canvas id="photo"></canvas>
<input type=button value="📷" onclick="snapshot()">
</div>
<script type="text/javascript" src="js/plugins/jquery.min.js"></script>
<script type="text/javascript" src="js/dist/pages/camera.js"></script>
</body>
</html>
Here is the CSS:
video {
width: 500px;
height: 500px;
object-fit: cover;
object-position: center;
}
.camera {
width: 500px;
height: 500px;
overflow: hidden;
}
Here is the TypeScript:
let canvas: HTMLCanvasElement;
let video: HTMLVideoElement;
$(window).on('load', async event => {
video = <HTMLVideoElement>document.getElementById('monitor');
canvas = <HTMLCanvasElement>document.getElementById('photo');
video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
video.onloadedmetadata = () => {
canvas.width = 500;
canvas.height = 500;
}
});
function snapshot() {
canvas.getContext('2d').drawImage(video, 0, 0);
}
Share
Improve this question
edited Nov 17, 2016 at 19:41
Get Off My Lawn
asked Nov 17, 2016 at 17:31
Get Off My LawnGet Off My Lawn
36.4k46 gold badges198 silver badges376 bronze badges
2
- have you tried absolutely positioning the elements on top of eachother? – Scott Murphy Commented Nov 17, 2016 at 17:55
- That will just move the elements around, that won't affect where it is drawn on the canvas. – Get Off My Lawn Commented Nov 17, 2016 at 18:24
1 Answer
Reset to default 2Your problem seems to be caused by the fact that the video
element keeps the aspect ratio of the video, while the canvas does not. Also remember that ctx.drawImage takes up to eight positional and size arguments:
context.drawImage(img/vid,sx,sy,swidth,sheight,x,y,width,height);
I did some testing, and found this to work pretty well, but your mileage may vary:
.drawImage(video,80,0,480,500,0,0,500,520);
I made a jsFiddle with these numbers, check it out to see if it works for you.
W3Schools has some great documentation on how these work, I suggest reading that: http://www.w3schools./tags/canvas_drawimage.asp
You could probably use the video's videoWidth
and videoHeight
attributes to calculate which numbers you need in drawImage
for different aspect ratio source videos