Jump to content
Fórum Script Brasil
  • 0

Webcam E Vb.net 2005


alexandremanowar

Question

E ae pessoal beleza

Eu baixei um programinha chamado conquercom, esse programa captura a imagem da minha webcam e mostra nele mesmo, e tem uma opção nesse programa que eu informo o diretório e ele fica salvando frames de imagens com o formato jpg no meu computador, esse programa só funciona se o driver da câmera estiver instalado caso contrário ele não encherga a câmera. Não sei em que linguagem foi feito esse programa mas me deparei com um problema e preciso desenvolver algo similar a isso e gostaria de desenvolver em vb.net.

O que preciso é bem simples crio um programa que mostra a tela o que minha webcam esta captando e deixo um botão "Salvar" abaixo da área que esta sendo mostrado a imagem clicando nesse botão ele me salva o frame do momento do clique. Porém não tenho idéia de como começar.

Alguém tem alguma idéia de como posso começar isso? Estou pesquisando mas não encontrei nada até o momento.

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0

E ae beleza Pessoal

Então fazendo pesquisas consegui alguns tutorias fiz umas junções e consegui fazer, deu trabalho mas graças a Deus saiu.

O progama ficou simples, ele é básico tem um picturebox onde é exida a imagem que esta sendo capturada pela câmera e tem 3 botões que nomei como iniciar,parar e salvar. Quando carrego o programa clico ni iniciar e ele ativa a cptura da iamgem da câmera e mostra no picturebox, quando clico no salvar ele copia a imagem atual da câmera o clipboard e fica ela na picturebox ou seja nesse momento ele para de caputurar imagens da câmera e deixa apenas a imagem que foi salva na memória e me abra um savefiledialog para salvar a imgem onde eu especificar.

Detalhe importante para isso estou usando a dll avicap32.dll que faz conexão e obtem dispositivos de vídeos.

O tutorial que me deu uma idéia legal de como fazer isso foi esta nesse link:

tutotial

Quem precisar de algo igual é s[o estudar bem esse tutorial e caso tenha mais dúvidas basta procurar referências sobre as bibliotecas e funções na net de forma especificada foi assim que consegui.

Agora a única coisa que ainda não consegui fazer e estou meio travado é o seguinte:

Quando eu clico no botão salvar ele me abra a janela para escolhar onde quero salvar e nomear o arquivo, porém eu gostaria de fazer diferente, gostaria de apenas clicar no botão salvar ele já vai salvar em um local e com o nome que eu já deixar programado no programa. Como eu posso fazer isso? Para que vocês possam entender vou postar o código

O meu programa ficou assim:

Imports System.Runtime.InteropServices
Public Class Form1

    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

    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

    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

    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

    Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click
        iDevice = lstDispositivos.SelectedIndex
        abreJanelaVisualizacao()

    End Sub

    Private Sub fechaJanelaVisualizacao()
        ' Desconecta do dispositivo
        SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, 0)

        ' fecha a chama a janela
        DestroyWindow(hHwnd)
    End Sub


    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

    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
End Class
Onde a parte que cuida do salvamento é:
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

Alguém sabe como fazer esse salvamento direto?

Valeu

Edited by alexandremanowar
Link to comment
Share on other sites

  • 0

E ae beleza

então galera consegui resolver o problema. Fiz um código que salva a imagem que esta no picturebox. o código ficou assim:

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

           ''essa parte captura a mensagem do picturebox e salva onde e com o nome que eu especificar
            Dim path As String = "C:\foto\teste.jpg"
            Dim img = New Bitmap(imgFoto.Image)
            img.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg)
       
       End If

    End Sub

Dessa forma basta eu clicar no botão salvar e ele salva no diretório que quiser automáticamente. Se alguém precisar salvar com caixa de diálogo é só usar o primeiro exemplo.

Quem precisar esta aí um exemplo completo.

Valeu

Link to comment
Share on other sites

  • 0

E a e pessoal beleza.

Então pessoal desde que terminei esse código acima estou tentando melhorar ele. Estou tentando fazer com que ele captura 6 webcams na tela. Para isso estou fazendo o seguinte:

1)Aumentei a quantidade de picturebox para 6 noemando conforme o nome que já tem ficou de picCapura .... picCaptura5

2)Aí vem a parte que estou me complicando acredito que vou ter que trabalhar em um loop para ele lançar as câmeras na picturabox ou trabalhar com System.Threading . Estou tentando das duas dormas mas não consegui nada ainda não deu pau na tela mas só me exibe uma imagem no ultimo picturebox que seria o picCaptura5 e as outras picturebox ficam com o fundo preto rsrssr não sei porque. Na verdade a parte que acredito que devo trabalhar é essa:

Private Sub abreJanelaVisualizacao()
....
 ' Abre a janela de visualização no picturebox
        hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _
        480, picCaptura.Handle.ToInt32, 0)
...
Porque é essa a parte do código que despera o Handle para a picCaptura. Acredito que tenho que tenho que trocar o nome fixo da picturebox por uma variável e deixar essa opção dentro de um loop que vai trocando o nome da picturebox. Acredito que fazendo isso e colocando um Threading nessa parte:
Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click
        iDevice = lstDispositivos.SelectedIndex
        abreJanelaVisualizacao()

         Dim th As New Thread(AddressOf abreJanelaVisualizacao(iDevice, picCapitura))
         th.Start()

    End Sub

Onde nessa linha:

Dim th As New Thread(AddressOf abreJanelaVisualizacao(iDevice, picCapitura))

Eu troco o picCapitura por todas as picturebox.

É assim que estou tentando fazer mas não deu certo até agora, será que alguém tem idéia de como consigo corrigir isso? Ou codificar de forma melhor? Dessa forma o programinha fica mais legal.

Valeu

Edited by alexandremanowar
Link to comment
Share on other sites

  • 0

E ae pessoal beleza

Então estou quase conseguindo resolver o problema de como capturar várias webcam no winform! Esta dando um problema de thread pelo menos é essa a mensagem de erro que estou recebendo.

Modifiquei um pouco o código para se adapatar melhor ao que estou fazendo, ele esta assim:

Imports System.Runtime.InteropServices
Imports System.Threading
Public Class Form1


    Public Class captura
        Public dev As Integer
        Public pic As PictureBox

        Public Sub New(ByVal idev As Integer, ByVal opic As PictureBox)
            dev = idev
            pic = opic
        End Sub
    End Class



    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

    'câmera 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

    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 existe dispositivo de captura instalado.")
            btnIniciar.Enabled = False
        End If

        btnParar.Enabled = False
        btnSalvar.Enabled = False
        picCaptura.SizeMode = PictureBoxSizeMode.StretchImage

    End Sub

    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

    Private Sub abreJanelaVisualizacao(ByVal cap As Object)
        Dim iHeight As Integer = cap.pic.Height
        Dim iWidth As Integer = cap.pic.Width



        ' Abre a janela de visualização no picturebox
        hHwnd = capCreateCaptureWindowA(cap.dev, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _
        480, cap.pic.Handle.ToInt32, cap.dev)

        ''mudar aqui a variavel.

        ' Conecta com o drive
        If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, cap.dev, 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, cap.pic.Width, cap.pic.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

    Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click
        iDevice = lstDispositivos.SelectedIndex

        Dim th As New Thread(New ParameterizedThreadStart(AddressOf abreJanelaVisualizacao))
        th.Start(New captura(0, picCaptura))

        Dim th2 As New Thread(New ParameterizedThreadStart(AddressOf abreJanelaVisualizacao))
        th2.Start(New captura(1, picCaptura2))
        

    End Sub

   

    
End Class

Então se vocês observarem o código criei uma class que recebe o device e os picturebox do thread que crei no botão iniciar do projeto. Tenho dois picturebox, logo criai 2 thread para mandar as informações para a class captura que vai mandar a informação para o método abreJanelaVisualizacao. Porém quando eu executo o programa e clico no botão iniciar do programa, ele marca a seguinte linha:

hHwnd = capCreateCaptureWindowA(cap.dev, WS_VISIBLE Or WS_CHILD, 0, 0, 640, _

480, cap.pic.Handle.ToInt32, cap.dev)

e coloca a seguinte mensagem de erro:

Operação entre threads inválida: controle 'picCaptura' acessado de um thread que não é aquele no qual foi criado.

Eu tenho duas picturebox no form uma é a picCaputra e outra a picCaptura2 e é nessa parte da linha cap.pic.Handle.ToInt32 que recebe o nome do picturebox que ele deve jopar a imagem, ou seja pelo que estou entendo esta tendo um problema entre a informação que thread esta jogando, mas ainda não consegui resolver. Alguém tem idéia de onde pode estar o erro? Acredito que resolvendo isso o programa fique funcionando.

Se alguém poder me ajudar eu agradeço.

Valeu

Valeu.

Link to comment
Share on other sites

  • 0
Guest --Victor --

eu preciso desse programa... você pode me passar ele pra min? meu MSN é victor.tassinari2006@hotmail.com

eu queria saber como eu transformo o codigo do programa em um programa de verdade

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Forum Statistics

    • Total Topics
      152k
    • Total Posts
      651.5k
×
×
  • Create New...