WebCamera.cs
5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace WebCam
{
public class WebCameraEventArgs : EventArgs
{
private System.Drawing.Bitmap bitMap;
private byte[] data;
public WebCameraEventArgs(byte[] videoData, System.Drawing.Bitmap bmp)
{
data = videoData;
bitMap = bmp;
}
public byte[] Data
{
get
{
return data;
}
}
public System.Drawing.Bitmap Bitmap
{
get
{
return bitMap;
}
}
}
public class WebCamera
{
public WebCamera(IntPtr handle, int width, int height)
{
mControlPtr = handle;
mWidth = width;
mHeight = height;
}
// delegate for frame callback
public delegate void RecievedFrameEventHandler(object sender,WebCameraEventArgs e);
public event RecievedFrameEventHandler RecievedFrame;
private IntPtr lwndC; // Holds the unmanaged handle of the control
private IntPtr mControlPtr; // Holds the managed pointer of the control
private int mWidth;
private int mHeight;
private API32.FrameEventHandler mFrameEventHandler; // Delegate instance for the frame callback - must keep alive! gc should NOT collect it
// Close the web camera
public void CloseWebcam()
{
this.capDriverDisconnect(this.lwndC);
}
// start the web camera
public bool StartWebCam()
{
byte[] lpszName = new byte[100];
byte[] lpszVer = new byte[100];
API32.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
this.lwndC = API32.capCreateCaptureWindowA(lpszName, API32.WS_VISIBLE + API32.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
if (this.capDriverConnect(this.lwndC, 0))
{
this.capPreviewRate(this.lwndC, 100);
//this.capPreview(this.lwndC, false); // resurssi, pivitetnk kuvaa jatkuvasti
API32.BITMAPINFO bitmapinfo = new API32.BITMAPINFO();
bitmapinfo.bmiHeader.biSize = API32.SizeOf(bitmapinfo.bmiHeader);
bitmapinfo.bmiHeader.biWidth = mWidth;
bitmapinfo.bmiHeader.biHeight = mHeight;
bitmapinfo.bmiHeader.biPlanes = 1;
bitmapinfo.bmiHeader.biBitCount = 24;
this.capSetVideoFormat(this.lwndC, ref bitmapinfo, API32.SizeOf(bitmapinfo));
this.mFrameEventHandler = new API32.FrameEventHandler(FrameCallBack);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
API32.SetWindowPos(this.lwndC, 0, 0, 0, mWidth, mHeight, 6);
return true;
}
return false;
}
// private functions
private bool capDriverConnect(IntPtr lwnd, short i)
{
return API32.SendMessage(lwnd, API32.WM_CAP_DRIVER_CONNECT, i, 0);
}
private bool capDriverDisconnect(IntPtr lwnd)
{
return API32.SendMessage(lwnd, API32.WM_CAP_DRIVER_DISCONNECT, 0, 0);
}
private bool capPreview(IntPtr lwnd, bool f)
{
return API32.SendMessage(lwnd, API32.WM_CAP_SET_PREVIEW, f, 0);
}
private bool capPreviewRate(IntPtr lwnd, short wMS)
{
return API32.SendMessage(lwnd, API32.WM_CAP_SET_PREVIEWRATE, wMS, 0);
}
private bool capSetCallbackOnFrame(IntPtr lwnd, API32.FrameEventHandler lpProc)
{
return API32.SendMessage(lwnd, API32.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
}
private bool capSetVideoFormat(IntPtr hCapWnd, ref API32.BITMAPINFO BmpFormat, int CapFormatSize)
{
return API32.SendMessage(hCapWnd, API32.WM_CAP_SET_VIDEOFORMAT, CapFormatSize, ref BmpFormat);
}
private bool capDlgVideoFormat(IntPtr lwnd)
{
return API32.SendMessage(lwnd, API32.WM_CAP_DLG_VIDEOFORMAT, 0, 0);
}
public void ShowConfigDialog()
{
CloseWebcam();
byte[] lpszName = new byte[100];
byte[] lpszVer = new byte[100];
API32.capGetDriverDescriptionA(0, lpszName, 100,lpszVer, 100);
this.lwndC = API32.capCreateCaptureWindowA(lpszName, API32.WS_VISIBLE + API32.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
if (capDriverConnect(this.lwndC ,0))
{
capDlgVideoFormat(this.lwndC);
CloseWebcam();
}
else
throw new Exception("Camera not found");
}
private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
{
API32.VIDEOHDR videoHeader = new API32.VIDEOHDR();
byte[] VideoData;
videoHeader = (API32.VIDEOHDR)API32.GetStructure(lpVHdr, videoHeader);
VideoData = new byte[videoHeader.dwBytesUsed];
API32.Copy(videoHeader.lpData, VideoData);
System.Drawing.Bitmap bmp = new Bitmap(mWidth, mHeight);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, mWidth, mHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
//System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, mWidth, mHeight), ImageLockMode.ReadWrite, PixelFormat.);
// Copy the data from memory to the Scan0 property of our Bitmap
/* int l = VideoData.Length;
for (int i = 0; i < l; i++)
{
Marshal.WriteByte(bmpData.Scan0, i, VideoData[i]);
}
*/
Marshal.Copy(VideoData, 0, bmpData.Scan0, VideoData.Length);
bmp.UnlockBits(bmpData);
if (this.RecievedFrame != null)
{
WebCameraEventArgs e = new WebCameraEventArgs(VideoData, bmp);
this.RecievedFrame(this,e);
}
}
}
}