HTML5: Como capturar imagem da webcam com Canvas?

31/05/2020 17:44

Para acessar a webcam, precisamos utilizar a função navigator.mediaDevices.getUserMedia. Essa função retorna uma Promise, contendo ou MediaStream. Com essa função podemos acessar o áudio ou vídeo do computador do usuário.

Obviamente, quando chamamos getUserMedia, o browser irá exibir um dialogo pedido a sobre o acesso a um dispositivo de mídia.

Nota: É importante deixar claro que getUserMedia só pode ser usado em ambientes considerado seguros. Portanto, se quiser utilizar em seu site ou aplicação web, esteja ciente que o mesmo possua SSL configurado para o domínio. Para testes, podemos usar o famoso localhost normalmente.

Para acessarmos a webcam, precisamos passar um parâmetro para getUserMedia, da seguinte forma:

navigator.mediaDevices.getUserMedia({video: true})
.then(function (mediaStream) {
  // nosso código aqui
})
.catch(function (err) {
  console.log('Não há permissões para acessar a webcam')
})

Se tudo ocorrer corretamente acima, teremos acesso á mediaStream. É através dela que poderemos capturar fotos da webcam. Precisamos agora que o usuário tenha uma pré-visualização da sua imagem. Para isso vamos utilizar uma tag video.

Basta adicionar ao código:

<video id="video"></video>
navigator.mediaDevices.getUserMedia({video: true})
.then(function (mediaStream) {
	var video = document.querySelector('#video');
  
     video.srcObject = mediaStream;
     video.play();
})
.catch(function (err) {
  console.log('Não há permissões para acessar a webcam')
})

Com isso, já podemos ver a imagem da nossa webcam sendo visualizada na tag video.

O próximo passo agora é fazer a captura do frame que precisamos para um canvas.

Vamos adicionar um canvas e um botão ao nosso código para fazermos isso, da seguinte forma:

<video id='video'></video>
<canvas id='canvas'></canvas>
<button id='capture'>Capturar</button>

Em seguida, vamos atribuir a função do click para #capture preencher o nosso Canvas.


document.querySelector('#capture').addEventListener('click', function (e) {
 
  var canvas = document.querySelector("#canvas");
  
  canvas.height = video.videoHeight;
  canvas.width = video.videoWidth;
  
  var context = canvas.getContext('2d');
  
  context.drawImage(video, 0, 0)
})

No código acima, nós primeiro definimos o tamhanho do canvas para ficar exatamente do mesmo tamanho do vídeo. Em seguida, utilizamos o context para desenhar a imagem capturada do vídeo. Toda vez que #capture é clicado, o frame específico será aplicado ao canvas.

Para você ter acesso à imagem do canvas, basta utilizar a função toBlob ou toDataURL.

Por exemplo, se quisermos fazer o upload do frame capturado, podemos simplesmente adicionar usar toBlob para adicionar o Blob a um FormData.

<button id="upload">Upload</button>
document.querySelector('#upload').addEventListener('click', function (e) {
 
  var canvas = document.querySelector("#canvas");
  
  canvas.toBlob(function (blob) {
  	var form = new FormData();
    form.append('image', blob, 'webcam.jpg');
    
  	var xhr = new XMLHttpRequest();
    xhr.open('POST', '/upload', true);
    xhr.onload = function(e) {
    	// upload concluído  
    };
    
    xhr.send(form);  
                              
  }, 'image/jpeg');
})

NOTA: Observe que no nosso exemplo, utilizamos no segundo parâmetro de toBlob o valor image/jpeg. Isso porque preferencialmente preferi converter o resultado do canvas para JPEG. Caso queira usar outro formato, é possível informar o MIME desejado, como image/png e afins.

Veja funcionando no Codepen

Artigos relacionados