Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

alexandremanowar

Imagem com vb.net 2005

Recommended Posts

E ae pessoal belezaEu 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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

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.

 

 

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

 

Então 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

Compartilhar este post


Link para o post
Compartilhar em outros sites

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 vcs 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.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.