namespace webcam
{
/**////
/// avicap 的摘要说明。
///
public class showvideo
{
// showvideo calls
[dllimport("avicap32.dll")] public static extern intptr capcreatecapturewindowa(byte[] lpszwindowname, int dwstyle, int x, int y, int nwidth, int nheight, intptr hwndparent, int nid);
[dllimport("avicap32.dll")] public static extern bool capgetdriverdescriptiona(short wdriver, byte[] lpszname, int cbname, byte[] lpszver, int cbver);
[dllimport("user32.dll")] public static extern bool sendmessage(intptr hwnd, int wmsg, bool wparam, int lparam);
[dllimport("user32.dll")] public static extern bool sendmessage(intptr hwnd, int wmsg, short wparam, int lparam);
[dllimport("user32.dll")] public static extern bool sendmessage(intptr hwnd, int wmsg, short wparam, frameeventhandler lparam);
[dllimport("user32.dll")] public static extern bool sendmessage(intptr hwnd, int wmsg, int wparam, ref bitmapinfo lparam);
[dllimport("user32.dll")] public static extern int setwindowpos(intptr hwnd, int hwndinsertafter, int x, int y, int cx, int cy, int wflags);
[dllimport("avicap32.dll")]public static extern int capgetvideoformat(intptr hwnd, intptr psvideoformat, int wsize );
// constants
public const int wm_user = 0x400;
public const int ws_child = 0x40000000;
public const int ws_visible = 0x10000000;
public const int swp_nomove = 0x2;
public const int swp_nozorder = 0x4;
public const int wm_cap_driver_connect = wm_user + 10;
public const int wm_cap_driver_disconnect = wm_user + 11;
public const int wm_cap_set_callback_frame = wm_user + 5;
public const int wm_cap_set_preview = wm_user + 50;
public const int wm_cap_set_previewrate = wm_user + 52;
public const int wm_cap_set_videoformat = wm_user + 45;
// structures
[structlayout(layoutkind.sequential)] public struct videohdr
{
[marshalas(unmanagedtype.i4)] public int lpdata;
[marshalas(unmanagedtype.i4)] public int dwbufferlength;
[marshalas(unmanagedtype.i4)] public int dwbytesused;
[marshalas(unmanagedtype.i4)] public int dwtimecaptured;
[marshalas(unmanagedtype.i4)] public int dwuser;
[marshalas(unmanagedtype.i4)] public int dwflags;
[marshalas(unmanagedtype.byvalarray, sizeconst=4)] public int[] dwreserved;
}
[structlayout(layoutkind.sequential)] public struct bitmapinfoheader
{
[marshalas(unmanagedtype.i4)] public int32 bisize ;
[marshalas(unmanagedtype.i4)] public int32 biwidth ;
[marshalas(unmanagedtype.i4)] public int32 biheight ;
[marshalas(unmanagedtype.i2)] public short biplanes;
[marshalas(unmanagedtype.i2)] public short bibitcount ;
[marshalas(unmanagedtype.i4)] public int32 bicompression;
[marshalas(unmanagedtype.i4)] public int32 bisizeimage;
[marshalas(unmanagedtype.i4)] public int32 bixpelspermeter;
[marshalas(unmanagedtype.i4)] public int32 biypelspermeter;
[marshalas(unmanagedtype.i4)] public int32 biclrused;
[marshalas(unmanagedtype.i4)] public int32 biclrimportant;
}
[structlayout(layoutkind.sequential)] public struct bitmapinfo
{
[marshalas(unmanagedtype.struct, sizeconst=40)] public bitmapinfoheader bmiheader;
[marshalas(unmanagedtype.byvalarray, sizeconst=1024)] public int32[] bmicolors;
}
public delegate void frameeventhandler(intptr lwnd, intptr lpvhdr);
// public methods
public static object getstructure(intptr ptr,valuetype structure)
{
return marshal.ptrtostructure(ptr,structure.gettype());
}
public static object getstructure(int ptr,valuetype structure)
{
return getstructure(new intptr(ptr),structure);
}
public static void copy(intptr ptr,byte[] data)
{
marshal.copy(ptr,data,0,data.length);
}
public static void copy(int ptr,byte[] data)
{
copy(new intptr(ptr),data);
}
public static int sizeof(object structure)
{
return marshal.sizeof(structure);
}
}
//web camera class
public class webcamera
{
// constructur
public webcamera(intptr handle, int width,int height)
{
mcontrolptr = handle;
mwidth = width;
mheight = height;
}
// delegate for frame callback
public delegate void recievedframeeventhandler(byte[] data);
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 showvideo.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 void startwebcam()
{
byte[] lpszname = new byte[100];
byte[] lpszver = new byte[100];
showvideo.capgetdriverdescriptiona(0, lpszname, 100,lpszver, 100);
this.lwndc = showvideo.capcreatecapturewindowa(lpszname, showvideo.ws_visible + showvideo.ws_child, 0, 0, mwidth, mheight, mcontrolptr, 0);
if (this.capdriverconnect(this.lwndc, 0))
{
this.cappreviewrate(this.lwndc, 66);
this.cappreview(this.lwndc, true);
showvideo.bitmapinfo bitmapinfo = new showvideo.bitmapinfo();
bitmapinfo.bmiheader.bisize = showvideo.sizeof(bitmapinfo.bmiheader);
bitmapinfo.bmiheader.biwidth = 352;
bitmapinfo.bmiheader.biheight = 288;
bitmapinfo.bmiheader.biplanes = 1;
bitmapinfo.bmiheader.bibitcount = 24;
this.capsetvideoformat(this.lwndc, ref bitmapinfo, showvideo.sizeof(bitmapinfo));
this.mframeeventhandler = new showvideo.frameeventhandler(framecallback);
this.capsetcallbackonframe(this.lwndc, this.mframeeventhandler);
showvideo.setwindowpos(this.lwndc, 0, 0, 0, mwidth , mheight , 6);
}
}
// private functions
private bool capdriverconnect(intptr lwnd, short i)
{
return showvideo.sendmessage(lwnd, showvideo.wm_cap_driver_connect, i, 0);
}
private bool capdriverdisconnect(intptr lwnd)
{
return showvideo.sendmessage(lwnd, showvideo.wm_cap_driver_disconnect, 0, 0);
}
private bool cappreview(intptr lwnd, bool f)
{return showvideo.sendmessage(lwnd, showvideo.wm_cap_set_preview , f, 0);}
private bool cappreviewrate(intptr lwnd, short wms)
{
return showvideo.sendmessage(lwnd, showvideo.wm_cap_set_previewrate, wms, 0);
}
private bool capsetcallbackonframe(intptr lwnd, showvideo.frameeventhandler lpproc)
{
return showvideo.sendmessage(lwnd, showvideo.wm_cap_set_callback_frame, 0, lpproc);
}
private bool capsetvideoformat(intptr hcapwnd, ref showvideo.bitmapinfo bmpformat, int capformatsize)
{
return showvideo.sendmessage(hcapwnd, showvideo.wm_cap_set_videoformat, capformatsize, ref bmpformat);
}
private void framecallback(intptr lwnd, intptr lpvhdr)
{
showvideo.videohdr videoheader = new showvideo.videohdr();
byte[] videodata;
videoheader = (showvideo.videohdr)showvideo.getstructure(lpvhdr,videoheader);
videodata = new byte[videoheader.dwbytesused];
showvideo.copy(videoheader.lpdata ,videodata);
if (this.recievedframe != null)
this.recievedframe (videodata);
}
}
}
下面是实现的代码
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
using webcam;
namespace webcam
{
/**////
/// form1 的摘要说明。
///
public class form1 : system.windows.forms.form
{
private system.windows.forms.panel panelpreview;
private system.windows.forms.button b_play;
private system.windows.forms.button b_stop;
/**////
/// 必需的设计器变量。
///
private system.componentmodel.container components = null;
webcamera wc;
public form1()
{
//
// windows 窗体设计器支持所必需的
//
initializecomponent();
//
// todo: 在 initializecomponent 调用后添加任何构造函数代码
//
}
/**////
/// 清理所有正在使用的资源。
///
protected override void dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.dispose();
}
}
base.dispose( disposing );
}
windows 窗体设计器生成的代码#region windows 窗体设计器生成的代码
/**////
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
///
private void initializecomponent()
{
this.b_play = new system.windows.forms.button();
this.panelpreview = new system.windows.forms.panel();
this.b_stop = new system.windows.forms.button();
this.suspendlayout();
//
// b_play
//
this.b_play.location = new system.drawing.point(280, 368);
this.b_play.name = "b_play";
this.b_play.tabindex = 0;
this.b_play.text = "&play";
this.b_play.click += new system.eventhandler(this.button1_click);
//
// panelpreview
//
this.panelpreview.location = new system.drawing.point(8, 8);
this.panelpreview.name = "panelpreview";
this.panelpreview.size = new system.drawing.size(344, 272);
this.panelpreview.tabindex = 1;
//
// b_stop
//
this.b_stop.enabled = false;
this.b_stop.location = new system.drawing.point(360, 368);
this.b_stop.name = "b_stop";
this.b_stop.tabindex = 2;
this.b_stop.text = "&stop";
this.b_stop.click += new system.eventhandler(this.b_stop_click);
//
// form1
//
this.autoscalebasesize = new system.drawing.size(6, 14);
this.clientsize = new system.drawing.size(464, 413);
this.controls.add(this.b_stop);
this.controls.add(this.panelpreview);
this.controls.add(this.b_play);
this.maximizebox = false;
this.minimizebox = false;
this.name = "form1";
this.text = "goodview test web camera";
this.load += new system.eventhandler(this.form1_load);
this.resumelayout(false);
}
#endregion
/**////
/// 应用程序的主入口点。
///
[stathread]
static void main()
{
application.run(new form1());
}
private void form1_load(object sender, system.eventargs e)
{
b_play.enabled = false;
b_stop.enabled = true;
panelpreview.size = new size(330,330);
wc = new webcamera( panelpreview.handle,panelpreview.width,panelpreview.height);
wc.startwebcam();
}
private void button1_click(object sender, system.eventargs e)
{
b_play.enabled = false;
b_stop.enabled = true;
panelpreview.size = new size(330,330);
wc = new webcamera( panelpreview.handle,panelpreview.width,panelpreview.height);
wc.startwebcam();
}
private void b_stop_click(object sender, system.eventargs e)
{
b_play.enabled = true;
b_stop.enabled = false;
wc.closewebcam();
}
}
}
新闻热点
疑难解答