Missed the action at the 2018 Chrome Dev Summit? Catch up with our playlist on the Google Chrome Developers channel on YouTube. Watch now.

Como capturar uma imagem do usuário

Atualmente, muitos navegadores têm o recurso de acessar inserções de dados de áudio e vídeo do usuário. No entanto, dependendo do navegador, essa pode ser uma experiência dinâmica e integrada ou delegada a outro aplicativo do dispositivo do usuário.

Comece com o simples e evolua aos poucos

A coisa mais fácil a se fazer é simplesmente solicitar ao usuário um arquivo pré-gravado. Faça isso criando um elemento "input" de arquivo simples e adicionando um filtro accept que indique que só podemos aceitar arquivos de imagem e que o ideal seria obtê-los diretamente da câmera.

<input type="file" accept="image/*" capture>

Esse método funciona em todas as plataformas. Em computadores, o usuário poderá carregar um arquivo de imagem do sistema de arquivos. No Safari para iOS, esse método abrirá o aplicativo da câmera, permitindo capturar uma imagem e enviá-la para a página da web. No Android, esse método dará ao usuário a opção de definir que aplicativo será usado para capturar a imagem antes de enviá-la para a página da web.

Em seguida, os dados podem ser ligados a um <form> ou manipulados com JavaScript pela detecção de um evento onchange no elemento "input" e, depois, lendo a propriedade files do target do evento.

Capturar um único quadro

Obter acesso ao arquivo de imagem é bem simples.

<input type="file" accept="image/*" capture="camera" id="camera">
<img id="frame">
<script>
  var camera = document.getElementById('camera');
  var frame = document.getElementById('frame');

  camera.addEventListener('change', function(e) {
    var file = e.target.files[0]; 
    // Do something with the image file.
    frame.src = URL.createObjectURL(file);
  });
</script>

Depois que você tiver acesso ao arquivo, pode fazer o que quiser com ele. Por exemplo, é possível:

  • Anexá-lo diretamente a um elemento <canvas> para poder manipulá-lo
  • Baixar no dispositivo do usuário
  • Carregá-lo em um servidor anexando-o a uma XMLHttpRequest

Embora usar o método do elemento "input" para obter acesso a imagens seja universal, é a opção menos vantajosa porque ele não está diretamente integrado à página da web e, em computadores, não pode acessar a webcam do usuário.

Acesse a câmera de forma interativa

Os navegadores modernos podem obter acesso direto à câmera, o que permite criar experiências totalmente integradas com a página web para que o usuário não precise sair do navegador em nenhum momento.

Aviso: acesso direto à câmera é um recurso poderoso e, por isso, requer autorização do usuário e o seu site precisa estar em uma origem segura (HTTPS).

Obtenha acesso à câmera

Podemos acessar a câmera e o microfone diretamente usando uma API na especificação WebRTC chamada getUserMedia(). Assim, enviamos uma solicitação de acesso às câmeras e microfones ao usuário.

Se a resposta for positiva, a API retornará um MediaStream que contém dados da câmera e poderemos anexá-lo a um elemento <video> e reproduzi-lo para ver uma prévia em tempo real ou anexá-lo a um <canvas> para obter uma imagem instantânea.

Para obter dados da câmera, basta definir video: true no objeto de restrições passado à API de getUserMedia()

<video id="player" controls autoplay></video>
<script>  
  var player = document.getElementById('player');

  var handleSuccess = function(stream) {
    player.srcObject = stream;
  };

  navigator.mediaDevices.getUserMedia({video: true})
      .then(handleSuccess);
</script>

Por si só, isso não é tão útil. Tudo que podemos fazer e obter os dados de vídeo e reproduzi-lo.

Tire uma foto com a câmera

Para acessar os dados brutos da câmera, temos que pegar o fluxo criado por getUserMedia() e processar os dados. Ao contrário da Web Audio, não há uma API de processamento de fluxo dedicada para vídeos na web, por isso temos que recorrer a um pouquinho do jeitinho brasileiro para capturar uma foto da câmera do usuário.

Esse processo acontece assim:

  1. Crie um objeto "canvas" que armazenará o quadro da câmera
  2. Obtenha acesso ao fluxo da câmera
  3. Anexe-o a um elemento "video"
  4. Quando quiser capturar um quadro preciso, adicione os dados do elemento "video" a um objeto "canvas" usando drawImage().

Pronto!

<video id="player" controls autoplay></video>
<button id="capture">Capture</button>
<canvas id="snapshot" width=320 height=240></canvas>
<script>
  var player = document.getElementById('player'); 
  var snapshotCanvas = document.getElementById('snapshot');
  var captureButton = document.getElementById('capture');

  var handleSuccess = function(stream) {
    // Attach the video stream to the video element and autoplay.
    player.srcObject = stream;
  };

  captureButton.addEventListener('click', function() {
    var context = snapshot.getContext('2d');
    // Draw the video frame to the canvas.
    context.drawImage(player, 0, 0, snapshotCanvas.width, 
        snapshotCanvas.height);
  });

  navigator.mediaDevices.getUserMedia({video: true})
      .then(handleSuccess);
</script>

Quando tiver os dados da câmera armazenados no "canvas", você vai poder fazer muitas coisas com eles. Como:

  • Carregá-los direto no servidor.
  • Armazenar localmente
  • Aplicar efeitos modernos à imagem

Pare de transmitir da câmera quando não for necessário

É uma boa prática parar de usar a câmera quando ela não é necessária. Isso não só economiza bateria e capacidade de processamento, mas também faz com que os usuários confiem no seu aplicativo.

Para parar de acessar a câmera, basta chamar stop() em cada trilha de vídeo do fluxo retornado por getUserMedia().

<video id="player" controls autoplay></video>
<button id="capture">Capture</button>
<canvas id="snapshot" width=320 height=240></canvas>
<script>
  var player = document.getElementById('player'); 
  var snapshotCanvas = document.getElementById('snapshot');
  var captureButton = document.getElementById('capture');
  var videoTracks;

  var handleSuccess = function(stream) {
    // Attach the video stream to the video element and autoplay.
    player.srcObject = stream;
    videoTracks = stream.getVideoTracks();
  };

  captureButton.addEventListener('click', function() {
    var context = snapshot.getContext('2d');
    context.drawImage(player, 0, 0, snapshotCanvas.width, snapshotCanvas.height);

    // Stop all video streams.
    videoTracks.forEach(function(track) {track.stop()});
  });

  navigator.mediaDevices.getUserMedia({video: true})
      .then(handleSuccess);
</script>

Peça autorização para usar a câmera com responsabilidade

Se o usuário ainda não tiver concedido acesso à câmera para o seu site, no instante em que você chamar getUserMedia, o navegador pedirá que o usuário autorize o seu site a acessá-la.

Os usuários odeiam receber solicitações de permissão de acesso a dispositivos importantes do seu aparelho e muitas vezes bloqueiam a solicitação ou a ignoram se não entendem por que a solicitação foi criada. A abordagem mais indicada é só pedir acesso à câmera na primeira vez em que ela for necessária. Depois que o usuário conceder acesso, ele não receberá mais solicitações de permissão de acesso. Porém, se o usuário não der a permissão, você não poderá acessar novamente, a menos que ele mude manualmente as configurações de permissão da câmera.

Aviso: pedir acesso à câmera durante o carregamento de uma página fará com que a maioria dos usuários não conceda permissão de acesso a ela.

Compatibilidade

Saiba mais sobre a implementação em navegadores para dispositivo móvel e computador: srcObject navigator.mediaDevices.getUserMedia()

Recomendamos também usar o paliativo adapter.js para proteger os aplicativos de mudanças na especificação WebRTC e diferenças de prefixo.