Você está na página 1de 7

Como tirar uma foto usando a

Webcam (Javascript + HTML)?


https://velhobit.com.br/programacao/como-tirar-uma-foto-usando-a-webcam-javascript-html.html

Disclaimer: Provavelmente a funcionalidade de webcam não está acessível via


navegador interno de aplicativo (como o navegador interno do app do Facebook ou
outro app mobile). Experimente direto em um navegador (mobile ou desktop).

O HTML5 nos trouxe diversas opções interessantes para desenvolvimento de RIAs


(Rich Internet Applications). Em diversos sistemas online, precisamos de uma foto da
pessoa que está sendo cadastrada. Para sistemas de hotéis, saúde, academias,
dentre outros, que precisam de maior identificação, podemos usar a webcam para
fazer a foto na hora que poderá ser usada em posterior conferência. Recurso esse
que também está disponível em dispositivos móveis.

A ideia é transformar a imagem corrente da webcam em uma imagem base64. Após


isso, converter essa codificação em uma imagem JPG e devolver o caminho – quase
como se fosse um upload. Dessa forma você poderá salvar apenas o caminho da
imagem no seu banco de dados, sem ficar um campo muito extenso ou que possa
falhar em dispositivos móveis. Neste exemplo, será usado Javascript puro, a fim de
universalizar para quem quiser utilizar em sua aplicação web.

HTML5
Vamos começar criando nosso exemplo com os elementos HTML. Tudo o que
realmente precisamos é de uma tag button e uma tag video, mas para poder
visualizar o exemplo, vamos colocar o retorno em um img, link da imagem gerada e
um textarea para vermos o base64.

<div class="area">
<video autoplay="true" id="webCamera"></video>
<input type="text" id="base_img" name="base_img"/>
<button type="button" onclick="takeSnapShot()"> Tirar foto e salvar </button>
<img id="imagemConvertida"/>
<p id="caminhoImagem" class="caminho-imagem"><a href="" target="_blank"></a></p>
<script src="script.js"></script>
</div>
Não precisamos necessariamente de um CSS para poder funcionar, mas, apenas
para exemplo, vamos colocar um CSSzinho…

body{
font-family: sans-serif;
margin: 0;
}

.area{
margin: 10px auto;
box-shadow: 0 10px 100px #ccc;
padding: 20px;
box-sizing: border-box;
max-width: 500px;
}

.area video{
width: 100%;
height: auto;
background-color: whitesmoke;
}

.area textarea{
width: 100%;
margin-top: 10px;
height: 80px;
box-sizing: border-box;
}

.area button{
-webkit-appearance: none;
width: 100%;
box-sizing: border-box;
padding: 10px;
text-align: center;
background-color: #068c84;
color: white;
text-transform: uppercase;
border: 1px solid white;
box-shadow: 0 1px 5px #666;
}

.area button:focus{
outline: none;
background-color: #0989b0;
}

.area img{
max-width: 100%;
height: auto;
}

.area .caminho-imagem{
padding: 5px 10px;
border-radius: 3px;
background-color: #068c84;
text-align: center;
}

.area .caminho-imagem a{
color: white;
text-decoration: none;
}

.area .caminho-imagem a:hover{


color: yellow;
}
Javascript
Agora vamos para a parte divertida. Basicamente vamos dividir nosso código em 3
partes: Chamar a webcam, tirar o instantâneo, e enviar/receber os dados do PHP.
Criaremos o arquivo script.js.

A função LoadCamera, irá transformar a webcam em uma espécie


de streamming local. Para isso, é necessário que o navegador tenha suporte a isso,
logo, precisamos de um navegador moderno com total compatibilidade a HTML5.
Basicamente, todos os navegadores modernos, então não pense em compatibilidade
com Internet Explorer.

function loadCamera(){
//Captura elemento de vídeo
var video = document.querySelector("#webCamera");
//As opções abaixo são necessárias para o funcionamento correto no iOS
video.setAttribute('autoplay', '');
video.setAttribute('muted', '');
video.setAttribute('playsinline', '');
//--

//Verifica se o navegador pode capturar mídia


if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode:
'user'}})
.then( function(stream) {
//Definir o elemento vídeo a carregar o capturado pela webcam
video.srcObject = stream;
})
.catch(function(error) {
alert("Oooopps... Falhou :'(");
});
}
}

Você deve ter notado que a função acima tem um comentário com alguns
parâmetros adicionais. Esses parâmetros são necessários para o funcionamento no
iOS.

Já a função takeSnapShot irá justamente tirar o instantâneo. Essa função irá criar um
elemento canvas e desenhar em seu conteúdo uma imagem matricial, baseada no
vídeo (um ctrl+c / ctrl+v automático, digamos assim). A partir daí podemos obter
o base64 desse canvas e utilizá-lo para enviar posteriormente.
function takeSnapShot(){
//Captura elemento de vídeo
var video = document.querySelector("#webCamera");

//Criando um canvas que vai guardar a imagem temporariamente


var canvas = document.createElement('canvas');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
var ctx = canvas.getContext('2d');

//Desenhando e convertendo as dimensões


ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

//Criando o JPG
var dataURI = canvas.toDataURL('image/jpeg'); //O resultado é um BASE64 de uma
imagem.
document.querySelector("#base_img").value = dataURI;

sendSnapShot(dataURI); //Gerar Imagem e Salvar Caminho no Banco


}

Você pode, inclusive, se quiser, já adicionar essa base64 em no src de um


elemento img.

Agora, precisamos enviar essa base64 para o PHP. Usaremos o PHP para salvar a
imagem em um arquivo jpg (você pode optar por png também). O PHP irá retornar,
posteriormente, um json com o caminho completo da imagem, que iremos carregar
no objeto img descrito no HTML supracitado. Faremos isso dinamicamente, por
técnica de Ajax, sem formulário, pois o submit de um form poderá ser usado
futuramente para a conclusão de um determinado cadastro:

function sendSnapShot(base64){
var request = new XMLHttpRequest();
request.open('POST', 'save_photos.php', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-
8');
<pre><code> request.onload = function() {
console.log(request);
if (request.status >= 200 && request.status < 400) {
//Colocar o caminho da imagem no SRC
var data = JSON.parse(request.responseText);
//verificar se houve erro
if(data.error){
alert(data.error);
return false;
}

//Mostrar informações
document.querySelector("#imagemConvertida").setAttribute("src", data.img);
document.querySelector("#caminhoImagem a").setAttribute("href", data.img);
document.querySelector("#caminhoImagem a").innerHTML = data.img.split("/")[1];
} else {
alert( "Erro ao salvar. Tipo:" + request.status );
}
};

request.onerror = function() {
alert("Erro ao salvar. Back-End inacessível.");
}

request.send("base_img="+base64); // Enviar dados</code></pre>


<p>}

PHP
No lado do PHP, basicamente, usaremos um $_POST para capturar o dado enviado
via Ajax pelo Javascript. Criaremos então o arquivo salvar_photos.php.

Não há muitos segredos, mas é importante se atentar a dois detalhes:

1. Os dados chegam com o + transformado em espaço, então precisamos


converter novamente para + com um replace.
2. Precisamos salvar apenas os dados mime, sem os cabeçalhos, logo
precisamos dar um explode para coletar apenas os dados.

Fora isso, basicamente colocamos os dados em um arquivo JPG e retornamos a


URL em json para ser lido pelo Javascript novamente.
<?php
if(!isset($_POST['base_img'])){
die("{\"error\": \" Flopou. Cadê o base_img?\"}");
}
$result = [];
$data = str_replace(" ","+",$_POST['base_img']); //O envio do dado pelo
XMLHttpRequest tende a trocar o + por espaço, por isso a necessidade de substituir.
$name = md5(time().uniqid());
$path = "snaps/{$name}.jpg";

//data
$data = explode(',', $data);

//Save data
file_put_contents($path, base64_decode(trim($data[1])));

//Print Data
$result['img'] = $path;
echo json_encode($result, JSON_PRETTY_PRINT);
?>

Uma vez tudo pronto, basta chamar a função loadCamera() no evento que você quer
que ele seja disparado.

Como sempre, deixamos o código disponível para quem quiser utilizar. Desta vez, o
código está no GitHub.

Follow @velhobit 20

Você também pode gostar