This is a simple class using "avicap32.dll" and "User32.dll" to grab pictures from your PC camera. In the following content you'll see the code of this class and how to use it.These system dlls can be very helpful to realize some special funciton.The example only shows how to grab pictures,it is also very easy for using to grab videos,you can have a try.
This article assumes you are familiar with C#.
The camera control class: Pick.cs
using
System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace CameraCapture
... {
/**//// <summary>
/// 一个控制摄像头的类
/// </summary>
public class Pick
...{
private const int WM_USER = 0x400;
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const int WM_CAP_START = WM_USER;
private const int WM_CAP_STOP = WM_CAP_START + 68;
private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
private const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
private const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
private const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
private const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
private const int WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;
private const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
private const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
private const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;
private const int WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;
private const int WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;
private const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;
private const int WM_CAP_SET_SCALE = WM_CAP_START + 53;
private const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
public static int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //选择摄像头
private IntPtr hWndC;
private bool bStat = false;
private IntPtr mControlPtr;
private int mWidth;
private int mHeight;
private int mLeft;
private int mTop;
/**//// <summary>
/// 初始化摄像头
/// </summary>
/// <param name="handle">控件的句柄</param>
/// <param name="left">开始显示的左边距</param>
/// <param name="top">开始显示的上边距</param>
/// <param name="width">要显示的宽度</param>
/// <param name="height">要显示的长度</param>
public Pick(IntPtr handle, int left, int top, int width, int height)
...{
mControlPtr = handle;
mWidth = width;
mHeight = height;
mLeft = left;
mTop = top;
}
[DllImport("avicap32.dll")]
private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
private static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);
[DllImport("User32.dll")]
private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
/**//// <summary>
/// 开始显示图像
/// </summary>
public void Start()
...{
if (bStat)
return;
bStat = true;
byte[] lpszName = new byte[100];
hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);
if (hWndC.ToInt32() != 0)
...{
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
}
return;
}
/**//// <summary>
/// 停止显示
/// </summary>
public void Stop()
...{
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
bStat = false;
}
/**//// <summary>
/// 抓图
/// </summary>
/// <param name="path">要保存bmp文件的路径</param>
public void GrabImage(string path)
...{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
}
/**//// <summary>
/// 录像
/// </summary>
/// <param name="path">要保存avi文件的路径</param>
public void Kinescope(string path)
...{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
}
/**//// <summary>
/// 停止录像
/// </summary>
public void StopKinescope()
...{
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
}
/**//// <summary>
///
/// </summary>
public void SetShow()
...{
SendMessage(hWndC, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
}
}
}
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace CameraCapture
... {
/**//// <summary>
/// 一个控制摄像头的类
/// </summary>
public class Pick
...{
private const int WM_USER = 0x400;
private const int WS_CHILD = 0x40000000;
private const int WS_VISIBLE = 0x10000000;
private const int WM_CAP_START = WM_USER;
private const int WM_CAP_STOP = WM_CAP_START + 68;
private const int WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
private const int WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
private const int WM_CAP_SAVEDIB = WM_CAP_START + 25;
private const int WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
private const int WM_CAP_SEQUENCE = WM_CAP_START + 62;
private const int WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
private const int WM_CAP_SEQUENCE_NOFILE = WM_CAP_START + 63;
private const int WM_CAP_SET_OVERLAY = WM_CAP_START + 51;
private const int WM_CAP_SET_PREVIEW = WM_CAP_START + 50;
private const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = WM_CAP_START + 6;
private const int WM_CAP_SET_CALLBACK_ERROR = WM_CAP_START + 2;
private const int WM_CAP_SET_CALLBACK_STATUSA = WM_CAP_START + 3;
private const int WM_CAP_SET_CALLBACK_FRAME = WM_CAP_START + 5;
private const int WM_CAP_SET_SCALE = WM_CAP_START + 53;
private const int WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52;
public static int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //选择摄像头
private IntPtr hWndC;
private bool bStat = false;
private IntPtr mControlPtr;
private int mWidth;
private int mHeight;
private int mLeft;
private int mTop;
/**//// <summary>
/// 初始化摄像头
/// </summary>
/// <param name="handle">控件的句柄</param>
/// <param name="left">开始显示的左边距</param>
/// <param name="top">开始显示的上边距</param>
/// <param name="width">要显示的宽度</param>
/// <param name="height">要显示的长度</param>
public Pick(IntPtr handle, int left, int top, int width, int height)
...{
mControlPtr = handle;
mWidth = width;
mHeight = height;
mLeft = left;
mTop = top;
}
[DllImport("avicap32.dll")]
private static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
private static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize);
[DllImport("User32.dll")]
private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
/**//// <summary>
/// 开始显示图像
/// </summary>
public void Start()
...{
if (bStat)
return;
bStat = true;
byte[] lpszName = new byte[100];
hWndC = capCreateCaptureWindowA(lpszName, WS_CHILD | WS_VISIBLE, mLeft, mTop, mWidth, mHeight, mControlPtr, 0);
if (hWndC.ToInt32() != 0)
...{
SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage(hWndC, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage(hWndC, WM_CAP_SET_SCALE, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage(hWndC, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage(hWndC, WM_CAP_SET_PREVIEW, 1, 0);
}
return;
}
/**//// <summary>
/// 停止显示
/// </summary>
public void Stop()
...{
SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);
bStat = false;
}
/**//// <summary>
/// 抓图
/// </summary>
/// <param name="path">要保存bmp文件的路径</param>
public void GrabImage(string path)
...{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_SAVEDIB, 0, hBmp.ToInt32());
}
/**//// <summary>
/// 录像
/// </summary>
/// <param name="path">要保存avi文件的路径</param>
public void Kinescope(string path)
...{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
SendMessage(hWndC, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, hBmp.ToInt32());
SendMessage(hWndC, WM_CAP_SEQUENCE, 0, 0);
}
/**//// <summary>
/// 停止录像
/// </summary>
public void StopKinescope()
...{
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
}
/**//// <summary>
///
/// </summary>
public void SetShow()
...{
SendMessage(hWndC, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
}
}
}
the form1.cs (using the pick.cs to realize some function)
using
System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace CameraCapture
... {
public partial class Form1 : Form
...{
public Form1()
...{
InitializeComponent();
}
[STAThread]
static void Main()
...{
Application.Run(new Form1());
}
private void Form1_Load(object sender, EventArgs e)
...{
pk = new Pick(this.pictureBox1.Handle, 0, 0, this.pictureBox1.Width, this.pictureBox1.Height);
pk.Start();
this.timer1.Enabled = true;
}
//save
private void button2_Click(object sender, EventArgs e)
...{
this.timer1.Stop();
this.timer1.Enabled = false;
try
...{
SaveFileDialog SaveFileDialog1 = new SaveFileDialog();
SaveFileDialog1.Filter = "bmp files (*.bmp)|*.bmp|jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";
SaveFileDialog1.FilterIndex = 2; //默认图片保存格式 JPG
SaveFileDialog1.RestoreDirectory = true;
SaveFileDialog1.FileName = "Pic01"; //默认图片保存名称 Pic01
if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
...{
pk.GrabImage(SaveFileDialog1.FileName);
}
}
catch
...{
}
wc.CloseWebcam();
}
private void timer1_Tick(object sender, EventArgs e)
...{
count++;
pk.GrabImage(count.ToString() + ".bmp");
}
//play
private void button1_Click(object sender, EventArgs e)
...{
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace CameraCapture
... {
public partial class Form1 : Form
...{
public Form1()
...{
InitializeComponent();
}
[STAThread]
static void Main()
...{
Application.Run(new Form1());
}
private void Form1_Load(object sender, EventArgs e)
...{
pk = new Pick(this.pictureBox1.Handle, 0, 0, this.pictureBox1.Width, this.pictureBox1.Height);
pk.Start();
this.timer1.Enabled = true;
}
//save
private void button2_Click(object sender, EventArgs e)
...{
this.timer1.Stop();
this.timer1.Enabled = false;
try
...{
SaveFileDialog SaveFileDialog1 = new SaveFileDialog();
SaveFileDialog1.Filter = "bmp files (*.bmp)|*.bmp|jpg files (*.jpg)|*.jpg|All files (*.*)|*.*";
SaveFileDialog1.FilterIndex = 2; //默认图片保存格式 JPG
SaveFileDialog1.RestoreDirectory = true;
SaveFileDialog1.FileName = "Pic01"; //默认图片保存名称 Pic01
if (SaveFileDialog1.ShowDialog() == DialogResult.OK)
...{
pk.GrabImage(SaveFileDialog1.FileName);
}
}
catch
...{
}
wc.CloseWebcam();
}
private void timer1_Tick(object sender, EventArgs e)
...{
count++;
pk.GrabImage(count.ToString() + ".bmp");
}
//play
private void button1_Click(object sender, EventArgs e)
...{
}
}
}
Nasky