locked
Webcam donot capture when cam window is inactive RRS feed

  • Question

  • hi

    i am creating a project in vb.net 2005. i am using a timer to save images that is captured by webcam.

    when i minimize the form . it save last captuerd image again and again.

    Webcam donot capture when cam window is inactive


    Ali Usman

    Friday, May 17, 2013 7:45 AM

Answers

  • Being that i did not see any constants or API functions in your code i could not tell how you had things working so here is a working copy of pretty much the same thing that captures the picture even if the window is minimized. To test it just create a new Form project with 1 Timer, 1 PictureBox, and 2 Buttons. (Button_Start) and (Button_Stop). You can change the directory and the picture name it is saved as inside the timer1_Tick event.

    Public Class Form1
        Dim fileno As Integer = 0
        Dim tmppic As String = My.Application.Info.DirectoryPath & "\Temp.dib"
        Dim hHwnd As IntPtr = IntPtr.Zero
        Dim iDevice As Integer = 0 'This is the device number
        Dim CamFrameRate As Integer = 15  'This is the Frames Per Second (FPS)
        Dim OutputHeight As Integer = 240 'Height of the picture
        Dim OutputWidth As Integer = 360  'Width of the picture
    
        Private Const WS_CHILD As Integer = &H40000000
        Private Const WS_VISIBLE As Integer = &H10000000
        Private Const WM_USER As Integer = &H400
        Private Const WM_CAP_DRIVER_CONNECT As Integer = WM_USER + 10
        Private Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_USER + 11
        Private Const WM_CAP_SET_PREVIEW As Integer = WM_USER + 50
        Private Const WM_CAP_SET_PREVIEWRATE As Integer = WM_USER + 52
        Private Const WM_CAP_SAVEDIB As Integer = WM_USER + 25
        Private Const WM_CAP_GRAB_FRAME_NOSTOP As Integer = WM_USER + 61
    
        Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As IntPtr
        Private 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 IntPtr, ByVal nID As Integer) As IntPtr
        Private Declare Function DestroyWindow Lib "user32" (ByVal hndw As IntPtr) As Boolean
    
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Timer1.Stop()
            SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, vbNullString)
            DestroyWindow(hHwnd)
            If System.IO.File.Exists(tmppic) Then System.IO.File.Delete(tmppic)
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Button_Stop.Enabled = False
            hHwnd = capCreateCaptureWindowA(iDevice.ToString, WS_VISIBLE Or WS_CHILD, 0, 0, OutputWidth, CShort(OutputHeight), PictureBox1.Handle, 0)
            If Not SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, iDevice, vbNullString) = IntPtr.Zero Then
                SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, CamFrameRate, vbNullString)
                SendMessage(hHwnd, WM_CAP_SET_PREVIEW, 1, vbNullString)
            Else
                MessageBox.Show("Error Connecting To Capture Device")
                Me.Close()
            End If
        End Sub
    
        Private Sub Button_Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Start.Click
            Timer1.Interval = 1000 'capture pic every 1 second
            Timer1.Start()
            Button_Start.Enabled = False
            Button_Stop.Enabled = True
        End Sub
    
        Private Sub Button_Stop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Stop.Click
            Timer1.Stop()
            Button_Start.Enabled = True
            Button_Stop.Enabled = False
        End Sub
    
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            SendMessage(hHwnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, vbNullString)
            SendMessage(hHwnd, WM_CAP_SAVEDIB, 0, tmppic)
            Dim bmp As New Bitmap(tmppic)
            bmp.Save("c:\test\Img" & fileno & ".jpg", Imaging.ImageFormat.Jpeg)
            fileno += 1
            bmp.Dispose()
        End Sub
    End Class





    • Proposed as answer by Mr. Monkeyboy Tuesday, May 21, 2013 9:57 PM
    • Edited by IronRazerz Wednesday, May 22, 2013 1:47 AM
    • Marked as answer by aliusman21284 Tuesday, May 28, 2013 7:51 AM
    Tuesday, May 21, 2013 3:54 PM

All replies

  • I would suggest you don't minimize the form. Maybe you should hide and unhide the form.

    You've taught me everything I know but not everything you know.

    Saturday, May 18, 2013 11:39 PM
  • You could do something like this.

    Option Strict On
    
    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Timer1.Interval = 100
            Timer1.Start()
        End Sub
    
    
        Private Sub Form1_Minimized(sender As Object, e As EventArgs) Handles Me.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                Me.WindowState = FormWindowState.Normal
                Me.Hide()
            End If
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            If My.Computer.Keyboard.AltKeyDown Then
                Me.Show()
            End If
        End Sub
    End Class


    You've taught me everything I know but not everything you know.

    Sunday, May 19, 2013 2:00 AM
  • Hi, It would help to see the code that is capturing the image and the code that is saving the image.
    Sunday, May 19, 2013 2:13 AM
  • i am using this code

    Public Class Form1
        Inherits DevComponents.DotNetBar.Office2007Form
    
        Dim fileno As Integer = 0
        Dim Data As IDataObject
        Dim Bmap As Image
        Dim str As String
        Private Sub OpenPreviewWindow()
            Dim iHeight As Integer = Me.PictureBox1.Height
            Dim iWidth As Integer = Me.PictureBox1.Width
           
            hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 640, 480, PictureBox1.Handle.ToInt32, 0)
            If SendMessage(hHwnd, WM_Cap_Paki_CONNECT, iDevice, 0) Then
                SendMessage(hHwnd, WM_Cap_SET_SCALE, True, 0)
                SendMessage(hHwnd, WM_Cap_SET_PREVIEWRATE, 66, 0)
                SendMessage(hHwnd, WM_Cap_SET_PREVIEW, True, 0)
                SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, PictureBox1.Width, PictureBox1.Height, SWP_NOMOVE Or SWP_NOZORDER)
            Else
                DestroyWindow(hHwnd)
            End If
        End Sub
    
        Private Sub ClosePreviewWindow()
            SendMessage(hHwnd, WM_Cap_Paki_DISCONNECT, iDevice, 0)
            DestroyWindow(hHwnd)
        End Sub
    
        Private Sub FrmCamera_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Call OpenPreviewWindow()
            Button1.Focus()
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Timer1.Enabled = True
        End Sub
    
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
           
            SendMessage(hHwnd, WM_Cap_EDIT_COPY, 0, 0)
          
            Data = Clipboard.GetDataObject()
            If Data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
                Bmap = CType(Data.GetData(GetType(System.Drawing.Bitmap)), Image)
                PictureBox1.Image = Bmap
                PictureBox1.Image.Save("c:\test\Img" & fileno & ".jpg")
                fileno += 1
    
            End If
            PictureBox1.Image.Dispose()
    
            If My.Computer.Keyboard.AltKeyDown Then
                Me.Show()
            End If
        End Sub
    
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Timer1.Enabled = False
        End Sub
    
        Private Sub Form1_Minimized(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Resize
            If Me.WindowState = FormWindowState.Minimized Then
                Me.WindowState = FormWindowState.Normal
                Me.Hide()
            End If
        End Sub
    
        Private Sub ButtonX1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonX1.Click
            Me.Close()
        End Sub
    End Class


    Ali Usman


    Tuesday, May 21, 2013 3:07 AM
  • Being that i did not see any constants or API functions in your code i could not tell how you had things working so here is a working copy of pretty much the same thing that captures the picture even if the window is minimized. To test it just create a new Form project with 1 Timer, 1 PictureBox, and 2 Buttons. (Button_Start) and (Button_Stop). You can change the directory and the picture name it is saved as inside the timer1_Tick event.

    Public Class Form1
        Dim fileno As Integer = 0
        Dim tmppic As String = My.Application.Info.DirectoryPath & "\Temp.dib"
        Dim hHwnd As IntPtr = IntPtr.Zero
        Dim iDevice As Integer = 0 'This is the device number
        Dim CamFrameRate As Integer = 15  'This is the Frames Per Second (FPS)
        Dim OutputHeight As Integer = 240 'Height of the picture
        Dim OutputWidth As Integer = 360  'Width of the picture
    
        Private Const WS_CHILD As Integer = &H40000000
        Private Const WS_VISIBLE As Integer = &H10000000
        Private Const WM_USER As Integer = &H400
        Private Const WM_CAP_DRIVER_CONNECT As Integer = WM_USER + 10
        Private Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_USER + 11
        Private Const WM_CAP_SET_PREVIEW As Integer = WM_USER + 50
        Private Const WM_CAP_SET_PREVIEWRATE As Integer = WM_USER + 52
        Private Const WM_CAP_SAVEDIB As Integer = WM_USER + 25
        Private Const WM_CAP_GRAB_FRAME_NOSTOP As Integer = WM_USER + 61
    
        Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As IntPtr
        Private 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 IntPtr, ByVal nID As Integer) As IntPtr
        Private Declare Function DestroyWindow Lib "user32" (ByVal hndw As IntPtr) As Boolean
    
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Timer1.Stop()
            SendMessage(hHwnd, WM_CAP_DRIVER_DISCONNECT, iDevice, vbNullString)
            DestroyWindow(hHwnd)
            If System.IO.File.Exists(tmppic) Then System.IO.File.Delete(tmppic)
        End Sub
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Button_Stop.Enabled = False
            hHwnd = capCreateCaptureWindowA(iDevice.ToString, WS_VISIBLE Or WS_CHILD, 0, 0, OutputWidth, CShort(OutputHeight), PictureBox1.Handle, 0)
            If Not SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, iDevice, vbNullString) = IntPtr.Zero Then
                SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, CamFrameRate, vbNullString)
                SendMessage(hHwnd, WM_CAP_SET_PREVIEW, 1, vbNullString)
            Else
                MessageBox.Show("Error Connecting To Capture Device")
                Me.Close()
            End If
        End Sub
    
        Private Sub Button_Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Start.Click
            Timer1.Interval = 1000 'capture pic every 1 second
            Timer1.Start()
            Button_Start.Enabled = False
            Button_Stop.Enabled = True
        End Sub
    
        Private Sub Button_Stop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Stop.Click
            Timer1.Stop()
            Button_Start.Enabled = True
            Button_Stop.Enabled = False
        End Sub
    
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            SendMessage(hHwnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, vbNullString)
            SendMessage(hHwnd, WM_CAP_SAVEDIB, 0, tmppic)
            Dim bmp As New Bitmap(tmppic)
            bmp.Save("c:\test\Img" & fileno & ".jpg", Imaging.ImageFormat.Jpeg)
            fileno += 1
            bmp.Dispose()
        End Sub
    End Class





    • Proposed as answer by Mr. Monkeyboy Tuesday, May 21, 2013 9:57 PM
    • Edited by IronRazerz Wednesday, May 22, 2013 1:47 AM
    • Marked as answer by aliusman21284 Tuesday, May 28, 2013 7:51 AM
    Tuesday, May 21, 2013 3:54 PM
  • thanks the problem is solve.

    can we set motion detection and brightness of preview window


    Ali Usman

    Thursday, May 23, 2013 6:54 AM
  • Hi,

     I have not experimented enough with this to figure out a way to do ether of the new questions but, someone else may have an answer or some tips on doing them. Also if any of the posts here helped solve your original question then please mark them as the answers. It will help other people with the same question find an answer.  :)

    Thursday, May 23, 2013 5:19 PM