C#学习笔记——摄像头
界面:
源码:
1: using System;
2: using System.Collections.Generic;
3: using System.ComponentModel;
4: using System.Data;
5: using System.Drawing;
6: using System.Linq;
7: using System.Text;
8: using System.Windows.Forms;
9:
10: //添加引用
11: using System.Runtime.InteropServices;
12: using System.Drawing.Imaging;
13:
14:
15: namespace Camera
16: {
17:
18: public partial class FormMain : Form
19: {
20: WebCamera wc;
21: //声明一个API函数
22: [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
23: private static extern bool BitBlt(
24: IntPtr hdcDest, // 目标 DC的句柄
25: int nXDest,
26: int nYDest,
27: int nWidth,
28: int nHeight,
29: IntPtr hdcSrc, // 源DC的句柄
30: int nXSrc,
31: int nYSrc,
32: System.Int32 dwRop // 光栅的处理数值
33: );
34:
35: public FormMain()
36: {
37: InitializeComponent();
38: }
39:
40: private void btnPlay_Click(object sender, EventArgs e)
41: {
42: btnPlay.Enabled = false;
43: btnStop.Enabled = true;
44: //panelPreview.Size = new Size(330, 330);
45: wc = new WebCamera(panelPreview.Handle, panelPreview.Width, panelPreview.Height);
46: wc.StartWebCam();
47: }
48:
49: private void FormMain_Load(object sender, EventArgs e)
50: {
51: btnPlay.Enabled = false;
52: btnStop.Enabled = true;
53: //panelPreview.Size = new Size(330, 330);
54: wc = new WebCamera(panelPreview.Handle, panelPreview.Width, panelPreview.Height);
55: wc.StartWebCam();
56: }
57:
58: private void btnStop_Click(object sender, EventArgs e)
59: {
60: btnPlay.Enabled = true;
61: btnStop.Enabled = false;
62: wc.CloseWebcam();
63: }
64:
65: private void btnPhoto_Click(object sender, EventArgs e)
66: {
67: //创建一个以当前控件区域屏幕为模板的图象
68: Graphics gPanel = this.panelPreview.CreateGraphics();
69:
70: Bitmap bmSave = new Bitmap(this.panelPreview.Width, this.panelPreview.Height); //用于保存图片的位图对象
71: Graphics gSave = Graphics.FromImage(bmSave);
72: //得到屏幕的DC
73: IntPtr dcPanel = gPanel.GetHdc();
74: //得到Bitmap的DC
75: IntPtr dcSave = gSave.GetHdc();
76: //调用此API函数,实现屏幕捕获
77: BitBlt(dcSave, 0, 0, this.panelPreview.Width, this.panelPreview.Height, dcPanel, 0, 0, 13369376);
78: //释放掉屏幕的DC
79: gPanel.ReleaseHdc(dcPanel);
80: //释放掉Bitmap的DC
81: gSave.ReleaseHdc(dcSave);
82: //以JPG文件格式来保存
83: bmSave.Save(@"D:/Photo.jpg", ImageFormat.Jpeg);
84: MessageBox.Show("当前图像已经保存为D盘Photo文件!");
85: }
86: }
87:
88:
89: //show Video class
90: public class showVideo
91: {
92: // showVideo calls
93: [DllImport("avicap32.dll")]
94: public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
95: [DllImport("avicap32.dll")]
96: public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
97: [DllImport("User32.dll")]
98: public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
99: [DllImport("User32.dll")]
100: public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
101: [DllImport("User32.dll")]
102: public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
103: [DllImport("User32.dll")]
104: public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
105: [DllImport("User32.dll")]
106: public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
107: [DllImport("avicap32.dll")]
108: public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize );
109:
110: // Constants
111: public const int WM_USER = 0x400;
112: public const int WS_CHILD = 0x40000000;
113: public const int WS_VISIBLE = 0x10000000;
114: public const int SWP_NOMOVE = 0x2;
115: public const int SWP_NOZORDER = 0x4;
116: public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;
117: public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
118: public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5;
119: public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
120: public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
121: public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
122:
123: // Structures
124: [StructLayout(LayoutKind.Sequential)] public struct VIDEOHDR
125: {
126: [MarshalAs(UnmanagedType.I4)] public int lpData;
127: [MarshalAs(UnmanagedType.I4)] public int dwBufferLength;
128: [MarshalAs(UnmanagedType.I4)] public int dwBytesUsed;
129: [MarshalAs(UnmanagedType.I4)] public int dwTimeCaptured;
130: [MarshalAs(UnmanagedType.I4)] public int dwUser;
131: [MarshalAs(UnmanagedType.I4)] public int dwFlags;
132: [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] public int[] dwReserved;
133: }
134:
135: [StructLayout(LayoutKind.Sequential)] public struct BITMAPINFOHEADER
136: {
137: [MarshalAs(UnmanagedType.I4)] public Int32 biSize ;
138: [MarshalAs(UnmanagedType.I4)] public Int32 biWidth ;
139: [MarshalAs(UnmanagedType.I4)] public Int32 biHeight ;
140: [MarshalAs(UnmanagedType.I2)] public short biPlanes;
141: [MarshalAs(UnmanagedType.I2)] public short biBitCount ;
142: [MarshalAs(UnmanagedType.I4)] public Int32 biCompression;
143: [MarshalAs(UnmanagedType.I4)] public Int32 biSizeImage;
144: [MarshalAs(UnmanagedType.I4)] public Int32 biXPelsPerMeter;
145: [MarshalAs(UnmanagedType.I4)] public Int32 biYPelsPerMeter;
146: [MarshalAs(UnmanagedType.I4)] public Int32 biClrUsed;
147: [MarshalAs(UnmanagedType.I4)] public Int32 biClrImportant;
148: }
149:
150: [StructLayout(LayoutKind.Sequential)] public struct BITMAPINFO
151: {
152: [MarshalAs(UnmanagedType.Struct, SizeConst=40)] public BITMAPINFOHEADER bmiHeader;
153: [MarshalAs(UnmanagedType.ByValArray, SizeConst=1024)] public Int32[] bmiColors;
154: }
155:
156: public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr);
157:
158: // Public methods
159: public static object GetStructure(IntPtr ptr,ValueType structure)
160: {
161: return Marshal.PtrToStructure(ptr,structure.GetType());
162: }
163:
164: public static object GetStructure(int ptr,ValueType structure)
165: {
166: return GetStructure(new IntPtr(ptr),structure);
167: }
168:
169: public static void Copy(IntPtr ptr,byte[] data)
170: {
171: Marshal.Copy(ptr,data,0,data.Length);
172: }
173:
174: public static void Copy(int ptr,byte[] data)
175: {
176: Copy(new IntPtr(ptr),data);
177: }
178:
179: public static int SizeOf(object structure)
180: {
181: return Marshal.SizeOf(structure);
182: }
183: }
184:
185: //Web Camera Class
186: public class WebCamera
187: {
188: // Constructur
189: public WebCamera(IntPtr handle, int width,int height)
190: {
191: mControlPtr = handle;
192: mWidth = width;
193: mHeight = height;
194: }
195:
196: // delegate for frame callback
197: public delegate void RecievedFrameEventHandler(byte[] data);
198: public event RecievedFrameEventHandler RecievedFrame;
199:
200: private IntPtr lwndC; // Holds the unmanaged handle of the control
201: private IntPtr mControlPtr; // Holds the managed pointer of the control
202: private int mWidth;
203: private int mHeight;
204:
205: private showVideo.FrameEventHandler mFrameEventHandler; // Delegate instance for the frame callback - must keep alive! gc should NOT collect it
206:
207: // Close the web camera
208: public void CloseWebcam()
209: {
210: this.capDriverDisconnect(this.lwndC);
211: }
212:
213: // start the web camera
214: public void StartWebCam()
215: {
216: byte[] lpszName = new byte[100];
217: byte[] lpszVer = new byte[100];
218:
219: showVideo.capGetDriverDescriptionA(0, lpszName, 100,lpszVer, 100);
220: this.lwndC = showVideo.capCreateCaptureWindowA(lpszName, showVideo.WS_VISIBLE + showVideo.WS_CHILD, 0, 0, mWidth, mHeight, mControlPtr, 0);
221:
222: if (this.capDriverConnect(this.lwndC, 0))
223: {
224: this.capPreviewRate(this.lwndC, 66);
225: this.capPreview(this.lwndC, true);
226: showVideo.BITMAPINFO bitmapinfo = new showVideo.BITMAPINFO();
227: bitmapinfo.bmiHeader.biSize = showVideo.SizeOf(bitmapinfo.bmiHeader);
228: bitmapinfo.bmiHeader.biWidth = 352;
229: bitmapinfo.bmiHeader.biHeight = 288;
230: bitmapinfo.bmiHeader.biPlanes = 1;
231: bitmapinfo.bmiHeader.biBitCount = 24;
232: this.capSetVideoFormat(this.lwndC, ref bitmapinfo, showVideo.SizeOf(bitmapinfo));
233: this.mFrameEventHandler = new showVideo.FrameEventHandler(FrameCallBack);
234: this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);
235: showVideo.SetWindowPos(this.lwndC, 0, 0, 0, mWidth , mHeight , 6);
236: }
237: }
238:
239: // private functions
240: private bool capDriverConnect(IntPtr lwnd, short i)
241: {
242: return showVideo.SendMessage(lwnd, showVideo.WM_CAP_DRIVER_CONNECT, i, 0);
243: }
244:
245: private bool capDriverDisconnect(IntPtr lwnd)
246: {
247: return showVideo.SendMessage(lwnd, showVideo.WM_CAP_DRIVER_DISCONNECT, 0, 0);
248: }
249:
250: private bool capPreview(IntPtr lwnd, bool f)
251: {
252: return showVideo.SendMessage(lwnd, showVideo.WM_CAP_SET_PREVIEW , f, 0);
253: }
254:
255: private bool capPreviewRate(IntPtr lwnd, short wMS)
256: {
257: return showVideo.SendMessage(lwnd, showVideo.WM_CAP_SET_PREVIEWRATE, wMS, 0);
258: }
259:
260: private bool capSetCallbackOnFrame(IntPtr lwnd, showVideo.FrameEventHandler lpProc)
261: {
262: return showVideo.SendMessage(lwnd, showVideo.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);
263: }
264:
265: private bool capSetVideoFormat(IntPtr hCapWnd, ref showVideo.BITMAPINFO BmpFormat, int CapFormatSize)
266: {
267: return showVideo.SendMessage(hCapWnd, showVideo.WM_CAP_SET_VIDEOFORMAT, CapFormatSize, ref BmpFormat);
268: }
269:
270: private void FrameCallBack(IntPtr lwnd, IntPtr lpVHdr)
271: {
272: showVideo.VIDEOHDR videoHeader = new showVideo.VIDEOHDR();
273: byte[] VideoData;
274: videoHeader = (showVideo.VIDEOHDR)showVideo.GetStructure(lpVHdr,videoHeader);
275: VideoData = new byte[videoHeader.dwBytesUsed];
276: showVideo.Copy(videoHeader.lpData ,VideoData);
277: if (this.RecievedFrame != null)
278: this.RecievedFrame (VideoData);
279: }
280: }
281:
282: }
作者:韩兆新
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。