Search code examples
javascripthtmlhtml5-canvashtml5-video

HTML5 camera stretches the picture


I'm using the HTML5 camera for taking picture. I have noticed that after the picture is captured, the final image width and height are stretched though I'm applying the same width and height for both video as well as canvas.

Please refer this JSFIDDLE

var video = document.querySelector("#videoElement");

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

if (navigator.getUserMedia) {       
    navigator.getUserMedia({video: true}, handleVideo, videoError);
}

function handleVideo(stream) {
    video.src = window.URL.createObjectURL(stream);
}

function videoError(e) {
    // do something
}
var v,canvas,context,w,h;
var imgtag = document.getElementById('imgtag');
var sel = document.getElementById('fileselect');

//document.addEventListener('DOMContentLoaded', function(){
    v = document.getElementById('videoElement');
    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d');
    w = canvas.width;
    h = canvas.height;

//},false);

function draw(v,c,w,h) {
    if(v.paused || v.ended) return false;
    context.drawImage(v,0,0,w,h);

   var uri = canvas.toDataURL("image/png");

   imgtag.src = uri;
}

document.getElementById('save').addEventListener('click',function(e){

    draw(v,context,w,h);


});
var fr;

sel.addEventListener('change',function(e){
    var f = sel.files[0];

    fr = new FileReader();
    fr.onload = receivedText;
    fr.readAsDataURL(f);
})

function receivedText() {        
    imgtag.src = fr.result;
}

Solution

  • Your code has hard-coded values for width and height, both for video and canvas elements.

    Avoid setting absolute sizes in both directions as the dimension of the video element can vary. You can set the size by using just the width or just the height, or by using CSS style/rule.

    For canvas you need to set the size based on the actual size of the video element. For this use the video element properties:

     video.videoWidth;
     video.videoHeight;
    

    You can apply a scale to those as you want, for example:

    scale = 300 / v.videoWidth;
    
    w = v.videoWidth * scale;
    h = v.videoHeight * scale;
    
    canvas.width = w;
    canvas.height = h;
    context.drawImage(v, 0, 0, w, h);
    

    Updated fiddle