Results 1 to 5 of 5

Thread: Webcam control via .NET

  1. #1

    Thread Starter
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Question Webcam control via .NET

    Hey all, I'm working on an interesting project for our shop floor.

    Basically, line operator puts a box into a loading station that has a webcam pointed down into it. Operator fills the box with an order. Operator then scans the barcode at the top of his sales order. Program then takes sales order, snaps some stills of the box with the webcam, and saves the data to a database.

    I have not even started looking for a webcam control library yet (I'm betting there are a couple out there on CodeProject and/or StackOverflow; maybe even on here) but I was wondering if anyone else has had to use .NET to control or just take stills from a webcam before and what you used. I want to know if there's some "popular library" out there others have used.

    Thanks in advance!
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  2. #2
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,401

    Re: Webcam control via .NET

    I remember using media player back on windows 7. But that was a long time ago.

    https://github.com/Microsoft/Windows.../SimpleCapture
    My Github - 1d3nt

  3. #3

    Thread Starter
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Webcam control via .NET

    Huh, thanks, I'll check that out and see if it still works. Could save me a lot of headache

    Trying to figure out Windows Image Acquisition (WIA) now.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  4. #4
    Frenzied Member
    Join Date
    May 2014
    Location
    Central Europe
    Posts
    1,388

    Re: Webcam control via .NET

    below is a class taken out of a project of mine that does a stream webcam capture using API.
    if you wanna take a still image, i recall that you can use some other WM_CAP message to get that in better quality than stream, but i guess at least the api declarations should be helpful.
    Code:
    Imports System.Runtime.InteropServices
    Imports System.Threading
    
    Public Class WebCam
        Implements PicProcessor.IPicProvider
    
    #Region "API Stuff"
    
        Private Declare Auto Function SendMessage _
          Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As IntPtr, _
          ByVal lParam As IntPtr) As IntPtr
    
        Private Declare Auto Function capCreateCaptureWindow _
          Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Int32, ByVal x As Int32, _
          ByVal y As Int32, ByVal nWidth As Int32, ByVal nHeight As Int32, ByVal hWndParent As IntPtr, _
          ByVal nID As Int32) As IntPtr
    
        Private Declare Function DestroyWindow _
          Lib "user32.dll" (ByVal hWnd As IntPtr) As Int32
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure VIDEOHDR
            Public lpData As IntPtr
            Public dwBufferLength As Int32
            Public dwBytesUsed As Int32
            Public dwTimeCaptured As Int32
            Public dwUser As Int32
            Public dwFlags As Int32
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Public dwReserved() As Int32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure CAPTUREPARMS
            Public dwRequestMicroSecPerFrame As Int32
            Public fMakeUserHitOKToCapture As Int32
            Public wPercentDropForError As Int32
            Public fYield As Int32
            Public dwIndexSize As Int32
            Public wChunkGranularity As Int32
            Public fUsingDOSMemory As Int32
            Public wNumVideoRequested As Int32
            Public fCaptureAudio As Int32
            Public wNumAudioRequested As Int32
            Public vKeyAbort As Int32
            Public fAbortLeftMouse As Int32
            Public fAbortRightMouse As Int32
            Public fLimitEnabled As Int32
            Public wTimeLimit As Int32
            Public fMCIControl As Int32
            Public fStepMCIDevice As Int32
            Public dwMCIStartTime As Int32
            Public dwMCIStopTime As Int32
            Public fStepCaptureAt2x As Int32
            Public wStepCaptureAverageFrames As Int32
            Public dwAudioBufferSize As Int32
            Public fDisableWriteCache As Int32
            Public AVStreamMaster As Int32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure BITMAPINFO
            Public bmiHeader As BITMAPINFOHEADER
            Public bmiColors() As RGBQUAD
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure BITMAPINFOHEADER
            Public biSize As Int32
            Public biWidth As Int32
            Public biHeight As Int32
            Public biPlanes As Int16
            Public biBitCount As Int16
            Public biCompression As Int32
            Public biSizeImage As Int32
            Public biXPelsPerMeter As Int16
            Public biYPelsPerMeter As Int16
            Public biClrUsed As Int32
            Public biClrImportant As Int32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure RGBQUAD
            Public rgbBlue As Byte
            Public rgbGreen As Byte
            Public rgbRed As Byte
            Public rgbReserved As Byte
        End Structure
    
        Private Const WS_CHILD As Int32 = &H40000000
        Private Const WS_VISIBLE As Int32 = &H10000000
    
        Private Const INVALID_HANDLE_VALUE As Int32 = -1
    
        Private Const WM_USER As Int32 = &H400
        Private Const WM_CAP_SET_CALLBACK_VIDEOSTREAM As Int32 = WM_USER + 6
        Private Const WM_CAP_DRIVER_CONNECT As Int32 = WM_USER + 10
        Private Const WM_CAP_DRIVER_DISCONNECT As Int32 = WM_USER + 11
        Private Const WM_CAP_DLG_VIDEOFORMAT As Int32 = WM_USER + 41
        Private Const WM_CAP_DLG_VIDEODISPLAY As Int32 = WM_USER + 43
        Private Const WM_CAP_GET_VIDEOFORMAT As Int32 = WM_USER + 44
        Private Const WM_CAP_SET_VIDEOFORMAT As Int32 = WM_USER + 45
        Private Const WM_CAP_DLG_VIDEOCOMPRESSION As Int32 = WM_USER + 46
        Private Const WM_CAP_SET_PREVIEW As Int32 = WM_USER + 50
        Private Const WM_CAP_SET_PREVIEWRATE As Int32 = WM_USER + 52
        Private Const WM_CAP_SET_SCALE As Int32 = WM_USER + 53
        Private Const WM_CAP_SEQUENCE As Int32 = WM_USER + 62
        Private Const WM_CAP_SEQUENCE_NOFILE As Int32 = WM_USER + 63
        Private Const WM_CAP_SET_SEQUENCE_SETUP As Int32 = WM_USER + 64
        Private Const WM_CAP_GET_SEQUENCE_SETUP As Int32 = WM_USER + 65
        Private Const WM_CAP_STOP As Int32 = WM_USER + 68
    #End Region
    
        Private Delegate Function VideoStreamCallback(ByVal hwnd As IntPtr, ByRef lpVHdr As VIDEOHDR) As Int32
        Private CallBack As New VideoStreamCallback(AddressOf HandleVideoStreamCallback)
    
        Public Event FrameCompleted()
    
        Private oCapParams As New CAPTUREPARMS
        Private oCapVideoFormat As BITMAPINFO
    
        Private hPreviewWindow As IntPtr
    
        <MarshalAs(UnmanagedType.ByValArray)> Public btPicData() As Byte
    
        Private cFrame As Int32
        Private isRunning As Boolean
    
        Private Structure YCbCrPixel
            Public Y As Int32
            Public Cb As Int32
            Public Cr As Int32
        End Structure
    
        Public ReadOnly Property FrameNumber() As Int32 Implements PicProcessor.IPicProvider.FrameNumber
            Get
                Return cFrame
            End Get
        End Property
    
        Public ReadOnly Property PicData() As Byte() Implements PicProcessor.IPicProvider.PicData
            Get
                PicData = btPicData
            End Get
        End Property
    
        Public ReadOnly Property Width() As Int32 Implements PicProcessor.IPicProvider.Width
            Get
                Return oCapVideoFormat.bmiHeader.biWidth
            End Get
        End Property
    
        Public ReadOnly Property Height() As Int32 Implements PicProcessor.IPicProvider.Height
            Get
                Return oCapVideoFormat.bmiHeader.biHeight
            End Get
        End Property
    
    
        Public Sub initCam(ByRef Preview As Panel)
            Cleanup()
    
            hPreviewWindow = capCreateCaptureWindow("name", WS_VISIBLE Or WS_CHILD, 0, 0, Preview.Width, Preview.Height, Preview.Handle, 0)
            SendMessage(hPreviewWindow, WM_CAP_DRIVER_CONNECT, 0, 0) 'schon jetzt ist die cam offen
            SendMessage(hPreviewWindow, WM_CAP_SET_PREVIEWRATE, 100, 0) 'ohne dem hier sieht man solange keinen preview bis WM_CAP_SEQUENCE aufgerufen wird
            SendMessage(hPreviewWindow, WM_CAP_SET_PREVIEW, 1, 0)
            SendMessage(hPreviewWindow, WM_CAP_SET_SCALE, 1, 0)
    
            Dim lpData As IntPtr
            'Get aktuelle Params, fYield ändern und Set, damit das Fenster sicher angezeigt wird:
            lpData = Marshal.AllocHGlobal(Marshal.SizeOf(oCapParams))
            If SendMessage(hPreviewWindow, WM_CAP_GET_SEQUENCE_SETUP, Marshal.SizeOf(oCapParams), lpData) <> 0 Then
                oCapParams = CType(Marshal.PtrToStructure(lpData, GetType(CAPTUREPARMS)), CAPTUREPARMS)
    
                With oCapParams
                    .fYield = 1
                    .fAbortLeftMouse = 0
                    .fAbortRightMouse = 0
                End With
    
                Marshal.StructureToPtr(oCapParams, lpData, True)
                If SendMessage(hPreviewWindow, WM_CAP_SET_SEQUENCE_SETUP, Marshal.SizeOf(oCapParams), lpData) <> 0 Then
                    'good
                Else
                    'Stop
                End If
            End If
            Marshal.FreeHGlobal(lpData)
    
            'user das format wählen lassen:
            'SendMessage(hPreviewWindow, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0)
            'SendMessage(hPreviewWindow, WM_CAP_DLG_VIDEOFORMAT, 0, 0)
            'SendMessage(hPreviewWindow, WM_CAP_DLG_VIDEODISPLAY, 0, 0) <- does not display a dialog for me
    
            'Get video format
            lpData = Marshal.AllocHGlobal(Marshal.SizeOf(oCapVideoFormat))
            If SendMessage(hPreviewWindow, WM_CAP_GET_VIDEOFORMAT, Marshal.SizeOf(oCapVideoFormat), lpData.ToInt32) <> 0 Then
                'oCapVideoFormat = CType(Marshal.PtrToStructure(lpData, GetType(BITMAPINFO)), BITMAPINFO)   'vorsicht! das kann offenbar in die hose gehen!
                oCapVideoFormat.bmiHeader = CType(Marshal.PtrToStructure(lpData, GetType(BITMAPINFOHEADER)), BITMAPINFOHEADER)
    
                'Modify und Set
                'oCapVideoFormat.bmiHeader.biCompression = BI_RGB  '<-diese settings hat meine cam nicht akzeptiert
                'oCapVideoFormat.bmiHeader.biBitCount = 32
                'oCapVideoFormat.bmiHeader.biWidth = 320
                'oCapVideoFormat.bmiHeader.biHeight = 240
                'Marshal.StructureToPtr(oCapVideoFormat.bmiHeader, lpData, True)
                'If SendMessage(hPreviewWindow, WM_CAP_SET_VIDEOFORMAT, Marshal.SizeOf(oCapVideoFormat), lpData.ToInt32) <> 0 Then
                'good
                'Else
                'Stop
                'End If
            End If
            Marshal.FreeHGlobal(lpData)
    
            'Arrays die für die Verarbeitung des Bildes notwendig sind vorbereiten
            With oCapVideoFormat.bmiHeader
                ReDim btPicData(.biSizeImage - 1I)
            End With
        End Sub
    
        Public Sub StartCapture()
            'Callback installieren & und capturing starten
            SendMessage(hPreviewWindow, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, Marshal.GetFunctionPointerForDelegate(CallBack))
            'SendMessage(hPreviewWindow, WM_CAP_SEQUENCE, 0, 0)    'geht auch, aber speichert zus. C:\CAPTURE.AVI
            SendMessage(hPreviewWindow, WM_CAP_SEQUENCE_NOFILE, 0, 0)  'nicht in C:\CAPTURE.AVI speichern
            isRunning = True
            cFrame = 0
        End Sub
    
        Public Sub StopCapture()
            If isRunning Then
                SendMessage(hPreviewWindow, WM_CAP_STOP, 0, 0)
                isRunning = False
            End If
        End Sub
    
        Public Sub Cleanup()
            StopCapture()
    
            If hPreviewWindow = 0 Then
                'derzt. nicht initialisiert
            ElseIf hPreviewWindow <> INVALID_HANDLE_VALUE Then
                SendMessage(hPreviewWindow, WM_CAP_DRIVER_DISCONNECT, 0, 0)
                DestroyWindow(hPreviewWindow)
                hPreviewWindow = INVALID_HANDLE_VALUE
            End If
        End Sub
    
        Protected Overrides Sub Finalize()
            Cleanup()
            MyBase.Finalize()
        End Sub
    
    
        Private Function HandleVideoStreamCallback(ByVal hwnd As IntPtr, ByRef lpVHdr As VIDEOHDR) As Int32
            'Debug.Print(String.Format("time ms captured: {0}, Used: {1}, of total {2} ", lpVHdr.dwTimeCaptured, lpVHdr.dwBytesUsed, lpVHdr.dwBufferLength.ToString))
            cFrame += 1
    
            'Debug.WriteLine(Thread.CurrentThread.ManagedThreadId & " " & pCallback)
            'Debug.Print(cFrame.ToString)
    
            Marshal.Copy(lpVHdr.lpData, btPicData, 0, lpVHdr.dwBytesUsed)
            RaiseEvent FrameCompleted()
        End Function
    
    
    End Class

  5. #5
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Webcam control via .NET

    Do yourself a favor and get WebEye.Controls.Winforms.WebCameraControl from NuGet

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width