Search code examples
javascriptgetusermedia

JS Get image directly from video stream as data url


How would I go directly from video capture to a data url in javascript? I want to display the image to the user as a resized version, but keep the full size image available. So, how would I do this?

var PhotoBooth = {
    onMediaStream: function(stream) {
        PhotoBooth.canvas = $('canvas')[0];
        PhotoBooth.context = PhotoBooth.canvas.getContext('2d');

        PhotoBooth.localVideo = $('video')[0];
        PhotoBooth.localVideo.src = window.URL.createObjectURL(stream);
    },
    noStream: function() {
        console.log('FAIL TO GET WEBCAM ACCESS');
    }
};

getUserMedia(
    {video: true},
    PhotoBooth.onMediaStream,
    PhotoBooth.noStream
);

This is how I am currently saving the image for upload:

PhotoBooth.context.drawImage(PhotoBooth.localVideo, 0, 0, 200, 150);
$('#preview').show();

Then I retrive the saved image like so:

var dataUrl = PhotoBooth.canvas.toDataURL();

I'd like to keep the canvas the same size it is by default, but keep the actual data. Basically, I want the canvas to show a re-sized version, but maintain the full size version.


Solution

  • Here, canvas maintains the original 640x480 snapshot (use https fiddle for Chrome):

    var start = () => navigator.mediaDevices.getUserMedia({ video: true })
      .then(stream => video.srcObject = stream)
      .catch(log);
    
    var canvas = document.createElement("canvas");
    canvas.width = 640;
    canvas.height = 480;
    
    var snap = () => {
      canvas.getContext('2d').drawImage(video, 0, 0, 640, 480);
      preview.getContext('2d').drawImage(canvas, 0, 0, 160, 120);
    }
    
    var log = msg => div.innerHTML += "<br>" + msg;
    <button onclick="start()">Start!</button>
    <button onclick="snap()">Snap!</button><div id="div"></div>
    <video id="video" width="160" height="120" autoplay></video>
    <canvas id="preview" width="160" height="120"></canvas>