VB .NET - Capturando imagens de uma WebCam
Este é um exemplo para captura de imagens de uma WebCam para VB.NET (VB 2005) , veja a versão para o VB6 no link: VB6 - Capturando imagens de uma WebCam.
Se você tiver a curiosidade de comparar o projeto VB6 com o projeto VB.NET perceberá que usamos a mesma API.
No VB 2005 Express o projeto irá usar as APIs do Windows para efetuar a captura de vídeo. A DLL avicap32.dll possui funções para conexão e obtenção de dispositivos de vídeos instalados no sistema Windows. As funções usadas serão:
a-
capCreateCaptureWindowA
b- capGetDriverDescriptionA
c- SendMessage
d- SetWindowPos
e- DestroyWindow
Veja também a colaboração : VB - Usando uma Webcam. para obter detalhes das APIs usadas. |
A seguir temos uma pequena explanação do processo como um todo:
O processo de captura de vídeo começa com a função capCreateCaptureWindowA. Quando chamada, esta função retorna um handle(identificador) para a nova janela. O handle(identificador) é um número de 32-bits que é usado para referenciar um objeto (neste caso, uma janela). Este handle é o fundamento para o restante do seu programa, e deve ser mantido em um local seguro.
Uma vez que a janela de captura é criada, você pode conectar a janela ao driver de vídeo. O driver de vídeo é instalado juntamente com sua câmera de vídeo. A conexão é feita com a mensagem WM_CAP_DRIVER_CONNECT. Isto irá "preencher" a janela com o primeiro driver de vídeo encontrado (índice 0).
Tenha em mente que poderia enviar esta mensagem para qualquer janela, mas somente esta janela especialmente criada com a capCreateCaptureWindow entenderá o que você está falando.
SendMessage lwnd, WM_CAP_DRIVER_CONNECT, 0, 0
A API SendMessage
é sempre chamada passando-se 4 parâmetros:
1 - Um handle(identificador) de janela (hwnd);
2 - Alguma mensagem para enviar à esta janela (wMsg);
3 - Um parâmetro (wParam) - 16-bits.
4 - E parâmetro (lParam) - 32-bits.
Veja também meu
artigo :
API - Abrindo e
fechando janelas MS-DOS
Vamos agora por a 'mão na massa' :
Inicie um novo projeto no Visual Basic 2005 Express do tipo Windows Application com o nome de WebCam e no formulário padrão form1.vb inclua os componentes: ListBox, PictureBox e Button conforme o leiaute da figura abaixo:
Para iniciar declare o namespace : Imports System.Runtime.InteropServices;
A seguir vamos declarar as funções das APIs usadas e as constantes relacionadas no formulário:
'constantes
usadas na DLL Const WM_CAP As Short = &H400S Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP + 10 Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP + 11 Const WM_CAP_EDIT_COPY As Integer = WM_CAP + 30 Const WM_CAP_SET_PREVIEW As Integer = WM_CAP + 50 Const WM_CAP_SET_PREVIEWRATE As Integer = WM_CAP + 52 Const WM_CAP_SET_SCALE As Integer = WM_CAP + 53 Const WS_CHILD As Integer = &H40000000 Const WS_VISIBLE As Integer = &H10000000 Const SWP_NOMOVE As Short = &H2S Const SWP_NOSIZE As Short = 1 Const SWP_NOZORDER As Short = &H4S Const HWND_BOTTOM As Short = 1 Dim iDevice As Integer = 0 ' ID do dispositivo atual Dim hHwnd As Integer ' manipulador da janela do visualizador Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Integer, _ ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer 'A função DestroyWindow destroi a janela especificada. 'Envia as mensagens WM_DESTROY e WM_NCDESTROY para a 'janela para destivá-la e remove o foco do teclado da mesma 'Library - User32 'Parametros - hWnd - (identica a janela a ser destruida) 'Retorna um valor diferente de zero se for executada com sucesso, 'caso contrario retorna zero Declare Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean Declare Function capCreateCaptureWindowA Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Integer, _ ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Short, ByVal hWndParent As Integer, ByVal nID As Integer) As Integer Declare Function capGetDriverDescriptionA Lib "avicap32.dll" (ByVal wDriver As Short, _ ByVal lpszName As String, ByVal cbName As Integer, ByVal lpszVer As String, ByVal cbVer As Integer) As Boolean |
Agora vamos definir o código para cada evento :
1- No evento Load do formulário vamos definir a carga dos dispositivos e a exibição do nome do mesmo no ListBox;
Private Sub
Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load 'verifica e carrega os dispositivos carregaDispositivos() ' se encontrou dispostivos instalados então exibe If lstDispositivos.Items.Count > 0 Then btnIniciar.Enabled = True lstDispositivos.SelectedIndex = 0 btnIniciar.Enabled = True Else lstDispositivos.Items.Add("Não dispositivo de captura instalado.") btnIniciar.Enabled = False End If btnParar.Enabled = False btnSalvar.Enabled = False picCaptura.SizeMode = PictureBoxSizeMode.StretchImage End Sub |
A rotina carregaDispositivos() possui o seguinte código:
Private Sub
carregaDispositivos() Dim strNome As String = Space(100) Dim strVer As String = Space(100) Dim bRetorna As Boolean Dim x As Integer = 0 '' Carrega os dispositivos em lstDevices Do ' Obtem o nome e a versão Driver bRetorna = capGetDriverDescriptionA(x, strNome, 100, strVer, 100) ' se existir um dispositivo inclui o nome da lista If bRetorna Then lstDispositivos.Items.Add(strNome.Trim) x += 1 Loop Until bRetorna = False End Sub |
Na rotina abreJanelaVisualização() iremos conectar com o drive e exibir as informações;
Private Sub
abreJanelaVisualizacao() Dim iHeight As Integer = picCaptura.Height Dim iWidth As Integer = picCaptura.Width ' Abre a janela de visualização no picturebox hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _ 480, picCaptura.Handle.ToInt32, 0) ' Conecta com o drive If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, iDevice, 0) Then ' 'Define a escala de previsão SendMessage(hHwnd, WM_CAP_SET_SCALE, True, 0) 'Define a taxa de visualização em milisegundos SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0) 'Iniciar a visualização da imagem a partir da camara SendMessage(hHwnd, WM_CAP_SET_PREVIEW, True, 0) ' Redimensiona a janela para se ajustar no picturebox SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picCaptura.Width, picCaptura.Height, SWP_NOMOVE Or SWP_NOZORDER) btnSalvar.Enabled = True btnParar.Enabled = True btnIniciar.Enabled = False Else ' ' Erro de conexão fecha a janela de dispostivos DestroyWindow(hHwnd) btnSalvar.Enabled = False End If End Sub |
O código do evento Click do botão iniciar abre a janela de visualização após obter o dispositivo instalado
Private Sub
btnIniciar_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnIniciar.Click iDevice = lstDispositivos.SelectedIndex abreJanelaVisualizacao() End Sub |
A rotina fechaJanelaVisualização() envia uma mensagem para desconexão da janela e destrói a janela;
Private Sub fechaJanelaVisualizacao() ' Desconecta do dispositivo SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, 0) ' fecha a chama a janela DestroyWindow(hHwnd) End Sub |
No evento Click do botão Parar fechamos a janela e definimos o estado de habilitação dos botões:
Private Sub btnParar_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnParar.Click fechaJanelaVisualizacao() btnSalvar.Enabled = False btnIniciar.Enabled = True btnParar.Enabled = False End Sub |
O código do evento Click do botão Salvar é o seguinte:
Private Sub
btnSalvar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnSalvar.Click Dim dados As IDataObject Dim bmap As Image ' Copia a imagem para o clipboard SendMessage(hHwnd, WM_CAP_EDIT_COPY, 0, 0) ' Obtem a imagem do clipboard e converte para bitmap dados = Clipboard.GetDataObject() If dados.GetDataPresent(GetType(System.Drawing.Bitmap)) Then bmap = CType(dados.GetData(GetType(System.Drawing.Bitmap)), Image) picCaptura.Image = bmap fechaJanelaVisualizacao() btnSalvar.Enabled = False btnParar.Enabled = False btnIniciar.Enabled = True If sfdImage.ShowDialog = System.Windows.Forms.DialogResult.OK Then bmap.Save(sfdImage.FileName, Imaging.ImageFormat.Bmp) End If End If End Sub Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing If btnParar.Enabled Then fechaJanelaVisualizacao() End If End Sub |
Executando o projeto e acionando o dispositivo da Webcam (Estou usando uma Microsoft LifeCam) iremos obter:
Pegue o projeto aqui: webCamNet.zip
Veja neste artigo como usar este recurso em um cadastro de clientes para capturar a foto do cliente:
Até o próximo artigo ...
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? |
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET