htmlcanvasgetusermedia

Rendering HTML5 Video to Canvas is squashing the image


I'm trying to take a photo from the user's webcam using getUserMedia.

The image from the camera is 640x480 (which presumably could be any size, depending on the user's webcam).

I've got a video tag, sized to 320x240 with CSS, and I'm rendering the webcam image onto it like this:

var $video = $('video');
navigator.getUserMedia({ video: true }, function (stream) {
    $video[0].mozSrcObject = stream;
    $video[0].play();
    localMediaStream = stream;
}, function () {
    console.log('sadtrombone.com');
});

This works fine.

Then, I'm taking a picture/still frame like this:

var ctx = $canvas[0].getContext('2d');
ctx.drawImage($video[0], 0, 0, $canvas[0].width, $canvas[0].height);

This draws the image onto the canvas, but it looks a bit blurry :/

Then, if I do this:

$('img).attr('src', $canvas[0].toDataURL('image/png'));

this renders the canvas to an image element, but the image is squashed, it's 300x150.

$canvas[0].width == 300 and $canvas[0].height == 150

What's going on?

Update

Interestingly/strangely - if I do this instead:

ctx.drawImage($video[0], 0, 0, 320, 240);

I still end up with a 300x150 image, but it's cropped. Although it does appear to be the correct aspect ratio from the source.

Update 2

Even stranger, if I do this:

ctx.drawImage($video[0], 0, 0, 640, 480);

I still end up with a 300x150 image, but it's the top left quarter of the image.


Solution

  • It would seem sizing the canvas with css is not enough. You have to do:

    canvas.width = 320;
    canvas.height = 240;
    

    then

    ctx.drawImage($video[0], 0, 0, 320, 240);
    

    works corretly