Capturando a imagem de uma WebCam em páginas ASP.NET
Leonel Fraga de Oliveira 24/03/2012 19:53

Olá, meus queridos! Vamos tirar a poeira do NM Tech (mais uma vez hehe) com um artigo de ótima utilidade para quem desenvolve aplicações ASP.NET e precisa capturar a imagem da WebCam instalada na máquina do usuário.

Supomos que você tenha uma aplicação Web para fazer cadastro de visitantes e que um dos requisitos seja a captura da foto do visitante. Como todos sabemos, uma aplicação Web não possui condições de acessar os recursos de hardware do computador onde roda o navegador cliente por conta própria. Nem via JavaScript.

Para isso podemos fazer o uso de plugins (escritos utilizando ActiveX ou Flash), estes disparando eventos e respondendo a comandos em JavaScript, que fazem a ponte entre o HTML e o acesso ao hardware do usuário.

O que iremos fazer aqui é utilizar a biblioteca jpgcam (acessem o site para maiores detalhes), que faz uso de um arquivo Flash para acessar os recursos da WebCam, um arquivo JavaScript, que faz a interface entre o Flash e a página que incorpora este script e uma página ASP.NET para processar o upload e gravar a imagem em um diretório do servidor Web.

No nosso projeto Web, temos o diretório camutils, que contém a biblioteca jpgcam (exceto o arquivo MP3 que simula o som de um obturador, que deve ficar no diretório raíz do site), com o arquivo webcam.js, que será a interface entre a página ASPX e o arquivo webcam.swf, que faz a grande “mágica” de acessar a WebCam.

Observem o código da página Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CapturaWebcamASPNET.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="camutils/webcam.js"></script>
</head>
<body>
    <form id="form1" runat="server">
	    <!-- Configura algumas opções -->
	    <script type="text/javascript" language="JavaScript">
	        webcam.set_api_url('Upload.aspx');//Página de destino do arquivo capturado
	        webcam.set_quality(90); // Qualidade do JPG (1 - 100)
	        webcam.set_shutter_sound(true); // Toca o som de câmera (o arquivo shutter.mp3, que vem com os "utilitários" da câmera, deve estar no diretório raíz do site)
	    </script>

        <table style="width:100%;" cellpadding="0" cellspacing="0">
            <tr>
                <td style="width:320px;height:240px;text-align:center;" valign="top">
                    <script type="text/javascript" language="JavaScript">
                        document.write(webcam.get_html(320, 240));
	                </script>
                    <input type="button" value="Configurar..." onclick="webcam.configure();" />
                    <input type="button" value="Capturar" onclick="take_snapshot();" />
                    <input type="button" value="Reset" onclick="webcam.reset();" />
                </td>
                <td style="width:320px;height:240px;" valign="top">
	                <!-- Desenha o HTML do Flash que faz a interface com a Webcam na resolução 320x240 -->
                    <div id="upload_results">

                    </div>
                </td>
            </tr>
        </table>

        <script type="text/javascript">
            webcam.set_hook('onComplete', 'my_completion_handler');

            function take_snapshot() {
                // Captura a imagem e submete ao servidor
                document.getElementById('upload_results').innerHTML = '<h1>Realizando Upload da Foto...</h1>';
                webcam.snap();
            }

            function my_completion_handler(msg) {
                // Extrai a URL da imagem do retorno de Upload.aspx
                if (msg.match(/(http://S+)/)) {
                    var image_url = RegExp.$1;
                    // show JPEG image in page
                    document.getElementById('upload_results').innerHTML =
					    '<img src="' + image_url + '">' +
                        '<h1>Upload Com Sucesso!</h1>' +
					    '<h3>URL do JPG: ' + image_url + '</h3>';

                    // reset camera for another shot
                    webcam.reset();
                }
                else alert("ASPNET Error: " + msg);
            }
        </script>

    </form>
</body>
</html>

Inicialmente incorporamos o script camutils/webcam.js (fiz algumas anotações neste arquivo, é importante dar uma olhadinha ;) ) em nossa página na tag <head> (poderia ser fora dela), e já dentro do <body> configuramos alguns parâmetros para serem passados ao Flash. Na instrução webcam.set_api_url() passamos o nome do arquivo que processará o upload. Não conheço o código da aplicação Flash, mas pelo seu comportamento, ele faz um HTTP POST diretamente para esta página (veremos ela mais adiante). No código original é um arquivo PHP que faz esse trabalho. Também configuramos outros parâmetros, que são a qualidade da imagem e se queremos o som do obturador.

Em seguida temos um layout básico de 2 colunas. Na esquerda chamamos a função webcam.get_html(altura,largura), que renderiza o HTML necessário para chamar o objeto Flash (arquivo camutils/webcam.swf) já passando os parâmetros correspondentes, que configuramos acima. Também temos três botões de controle a saber:

- Configurar...: Dispara a rotina do Flash para configurar a webcam. Chama o método da API webcam.configure() em seu método onClick;

- Capturar: Captura a imagem, chamando a função take_snapshot() que veremos em seguida.

- Reset: Prepara a câmera para nova captura. Chama a função da API webcam.reset().

PS: o objeto JavaScript “webcam” é definido dentro de camutils/webcam.js.

Na coluna da direita temos um <div> que receberá a imagem capturada.

No segundo bloco JavaScript, declaramos uma função que “ouvirᔠo evento onComplete do objeto da WebCam. Este evento será ouvido pela função “my_completion_handler” definida abaixo. Este evento recebe um parâmetro, que é a resposta da página Upload.aspx, que deverá retornar a URL da imagem em caso de sucesso, ou outra mensagem em caso de erro.

Em caso de sucesso, esta função escreverá um HTML no <div> “upload_results”, que conterá um <img> com a URL retornada. Caso contrário, disparamos um alert() com a mensagem de erro.

A checagem de erro é feita através de uma expressão regular. Se esta expressão contiver os padrões de uma URL, será válida.

A função take_snapshot() não tem segredo. Ela apenas dispara o método webcam.snap(). Este método aciona um método correspondente no Flash, que captura a foto da webcam e faz um HTTP POST para a página Upload.aspx. Após isso, o método que declaramos em onComplete (função my_completion_handler) será disparado.

E agora, como processamos o HTTP POST gerado pelo Flash na página Upload.aspx e retornamos como resposta a URL da imagem? Vamos ao código:

protected void Page_Load(object sender, EventArgs e)
{
	if (!IsPostBack)
	{
		try
		{
			string Dir = Server.MapPath("uploads");
			string FileName = String.Format("{0:ddMMyyyyhhmmss}.jpg", DateTime.Now);

			string CompleteFileName = String.Format("{0}{1}", Dir, FileName);

			using (FileStream fs = new FileStream(CompleteFileName, FileMode.Create))
			{
				byte[] buffer = new byte[Request.InputStream.Length];
				Request.InputStream.Read(buffer, 0, (int)Request.InputStream.Length);
				fs.Write(buffer, 0, buffer.Length);
			}

			string URLSaida = String.Format("{0}://{1}{2}{3}", Request.Url.Scheme, Request.Url.GetComponents(UriComponents.HostAndPort, UriFormat.Unescaped), "/uploads/", FileName);
			Response.Clear();
			Response.Write(URLSaida);
		}
		catch
		{
			Response.Clear();
			Response.Write("ERROR: Erro ao salvar imagemn");
		}
		Response.End();
	}
}

Agora sim trabalharemos no server-side!

Primeiro checamos se não é realizado um postback (evita que o Page_Load seja executado mais de uma vez), e configuramos o diretório (no Servidor Web) onde gravaremos as fotos e o nome que o arquivo terá. Como diretório, criei um diretório uploads no diretório raíz do site e guardamos seu caminho físico, usando o método Server.MapPath, passando o nome da pasta uploads como parâmetro, na variável Dir. Como nome de arquivo, gravaremos a data atual, incluíndo dia, mês, ano, minuto e segundo (em um ambiente de produção, inclua também os milissegundos ou concatene outra coisa, como a SessionID, para não ter risco de duplicar o nome do arquivo). Não esqueça que o diretório deve ter permissão de gravação para a conta de usuário que roda o processo no servidor que executa a página!

Após isso, guardamos o caminho físico completo do novo arquivo na variável CompleteFileName.

O arquivo Flash gerou um HTTP POST para a página Upload.aspx, diretamente. O conteúdo dele está na InputStream de nossa página processadora do upload. Salvamos esta InputStream no arquivo que nomeamos acima através de um FileStream.

Beleza, gravamos a foto no servidor, e agora precisamos retornar a URL da foto (esta Web, não física) para ser processada e exibida na página pela função que ouve o evento onComplete do objeto webcam em Default.aspx.

Geramos a URL de saída através do Scheme da URL (o protocolo, como o http://), do Host e da porta (exemplo: localhost:3000, e caso não tenha porta declarada - porta 80 - só localhost), do diretório onde vamos gravar a foto, e o nome do arquivo jpg (somente o nome, na variável FileName, sem o path físico). Concatenamos tudo isso e guardamos na variável URLSaida.

Para “jogar” essa URL na resposta, não basta apenas dar um Response.Write(URLSaida). Isto fará com que todo o HTML da página também vá junto, e somente queremos a URL. Para fazer isso, limpamos a saída com um Response.Clear() e em seguida sim, damos um Response.Write(URLSaida) e após um Response.End() para que a página seja imediatamente devolvida.

Após todo este processo, você visualizará a imagem capturada à direita e a WebCam estará pronta para outra captura.

Embora o artigo seja um pouquinho longo, não é difícil usar. Baixe o código-fonte exemplo, e você verá que não tem segredo. No próximo artigo vamos ver uma aplicação prática disso tudo, só que em vez de salvar em um arquivo, salvaremos em Banco de Dados.

Tenha bons sistemas Web ASP.NET com captura de foto!

Projeto ASP.NET com captura de imagem via WebCam (básico) (.NET Framework 4.0 e VisualStudio 2010, mas nada impede que seja portada para outros... vejam, o original é em PHP!) </P:

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus