C#.net编写摄像头驱动程序,用avicap32.dll

271 篇文章 2 订阅
215 篇文章 2 订阅

作者:zzmdegm

转自:http://blog.csdn.net/zzmdegm/article/details/1915364


装了摄像头后一般会有 avicap32.dll文件,没有一样可以用这些代码。

不需要在解决方案里面引用这个.dll文件。

下面有二种写法的例子:

例一:

 

using  System;
using  System.Runtime.InteropServices;
using  System.Drawing;
using  System.Drawing.Imaging;

namespace  WinVideo
{
    
/// <summary>
    
/// webcam 的摘要说明。
    
/// </summary>

    public class webcam
    
{
        
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;
        
private IntPtr hWndC;
        
private bool bStat = false;

        
private IntPtr mControlPtr;
        
private int mWidth;
        
private int mHeight;
        
private int mLeft;
        
private int mTop;
        
private string GrabImagePath="";
        
private string KinescopePath="";

        
/// <summary>
        
/// 初始化摄像头
        
/// </summary>
        
/// <param name="handle">控件的句柄</param>
        
/// <param name="left">开始显示的左边距</param>
        
/// <param name="top">开始显示的上边距</param>
        
/// <param name="width">要显示的宽度</param>
        
/// <param name="height">要显示的长度</param>

        public webcam(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,long 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()
        
{
            IntPtr hBmp
=Marshal.StringToHGlobalAnsi(GrabImagePath);
            SendMessage(hWndC,WM_CAP_SAVEDIB,
0,hBmp.ToInt64());

        }


        
/// <summary>
        
/// 录像
        
/// </summary>
        
/// <param name="path">要保存avi文件的路径</param>

        public void Kinescope()
        
{
            IntPtr hBmp
=Marshal.StringToHGlobalAnsi(KinescopePath);
            SendMessage(hWndC,WM_CAP_FILE_SET_CAPTURE_FILEA,
0,hBmp.ToInt64());
            SendMessage(hWndC,WM_CAP_SEQUENCE,
0,0);
        }


        
/// <summary>
        
/// 停止录像
        
/// </summary>

        public void StopKinescope()
        
{
            SendMessage(hWndC,WM_CAP_STOP,
0,0);
        }

    }

}

对该类的调用:

 

         public  webcam wcam = null ;
        
private   void  Form1_Load( object  sender, System.EventArgs e)
        
{    
            start();
            
this.btnKinescopeStop.Enabled=false;
        }


        
private   void  btnStar_Click( object  sender, System.EventArgs e)
        
{        
            wcam.Start();
        }


        
private   void  btnStop_Click( object  sender, System.EventArgs e)
        
{
            wcam.Stop();
        }


        
private   void  btnSnapPic_Click( object  sender, System.EventArgs e)
        
{
            
//得到路径。例:d:/a.bmp
            string myPath=this.txtPath.Text;
            
if(myPath=="")
            
{
                MessageBox.Show(
"必须填写路径!");
                
return;
            }

            
else
            
{
                wcam.grabImagePath
=myPath;
                wcam.GrabImage();
                MessageBox.Show(
"截图成功!");
            }

        }

        
public   void  start()
        
{
            
//以panel1为容器显示视频内容
            wcam=new webcam(panel1.Handle,0,0,this.panel1.Width,this.panel1.Height);        
            wcam.Start();
        }


        
private   void  panel1_SizeChanged( object  sender, System.EventArgs e)
        
{
            wcam.Stop();
            wcam.Height
=this.panel1.Height;
            wcam.Width
=this.panel1.Width;
            wcam.Start();
        }

        
        
private   delegate   void  delegateKinescope();
        
private   void  btnKinescopeBegin_Click( object  sender, System.EventArgs e)
        
{
            
//得到路径。例:d:/a.avi
            string myPath=this.txtPath.Text;
            
if(myPath=="")
            
{
                MessageBox.Show(
"必须填写路径!");
                
return;
            }

            
else
            
{
                wcam.kinescopePath
=myPath;
                delegateKinescope myK
=new delegateKinescope(wcam.Kinescope);
                Thread threadKinescope
=new Thread(new ThreadStart(myK));
                threadKinescope.Start();
                
this.btnKinescopeBegin.Enabled=false;
                
this.btnKinescopeStop.Enabled=true;
            }
        
        }

        
public   void  starKinescope()
        
{
            delegateKinescope myK
=new delegateKinescope(wcam.Kinescope);
        }


        
private   void  btnKinescopeStop_Click( object  sender, System.EventArgs e)
        
{
            wcam.StopKinescope();
            
this.btnKinescopeBegin.Enabled=true;
            
this.btnKinescopeStop.Enabled=false;            
        }

例二:

 

using  System;
using  System.Runtime.InteropServices;

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, 00, 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, 000, 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, 00);
        }

        
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);
        }

    }


}

调用代码:

 

        WebCamera wc;

        
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();
        }


另提供一种把显示的视频转成Image对象的方法:
using System.Windows.Forms;
//捕获视频成Image对象
public Image CatchVideo()
{
//SendMessage(this.hHwnd, 0x41e, 0, 0);
SendMessage(this.hWndC, 0x41e, 0, 0);

IDataObject obj1 = Clipboard.GetDataObject();
Image getIma = null;
if (obj1.GetDataPresent(typeof(Bitmap)))
{
Image image1 = (Image)obj1.GetData(typeof(Bitmap));
getIma = image1;
}
return getIma;
}


例一在转到2005后会报错:
检测到 PInvokeStackImbalance
Message: 对 PInvoke 函数“WindowsApplication1!UserLib.Device.PCCamera::SendMessage”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。
错误首次发生在这一行代码: SendMessage(hWndC, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
经过分析发现所有调用SendMessage函数的地方都会出现以上错误
于是查看DLLImport:
[DllImport("User32.dll")]
private static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, long lParam);
原来是因为WinAPI的long类型是32位的,而C#的long是64位的,这就导致堆栈不对称,引发错误.

原因:(http://discuss.develop.com/archives/wa.exe?A2=ind0512c&amp;L=dotnet-winforms&amp;D=0&amp;T=0&amp;P=8094)
在.NET2.0中加入了MDA(managed debugging assistant), 在平台调用时后会检查栈的指针, 如果发现不平衡, 就会抛出PInvokeStackImbalance异常; 而在.NET1.1中不会检查, 所以不会捕获到异常, 但在运行时会导致不稳定.

解决方法:
将最后一个”long lParam” 改为 “int wParam”, 因为C#中int是32位的. 并且将之后有涉及到SendMessage函数的参数适当地转成int型就可以了.
但是, 之后查阅了资料http://www.pinvoke.net/default.aspx/user32/SendMessage.html
发现先前的解决方案还有不合适的地方, 应该将其中的 ”wParm” 和 ”lParm” 参数的类型都转成IntPtr类型,并且将后面涉及到的参数的 ”0” 改为 “IntPtr.Zero”. 因为如果使用int类型,那么这段代码在64位的Windows上面将会无法正常运行.

总结:
我们在调用WinAPI时要特别小心, 因为WinAPI和C#的数据类型不是完全一样, 就好像在WinAPI中的long类型在C#中就是int类型, 如果没有处理好类型问题, 就很可能会导致堆栈的不平衡,引发PInvokeStackImbalance错误, 但是这类错误在.NET1.1下不会被暴露出来, 所以在从.NET1.1升级到.NET2.0时要特别注意此类问题.

另提供一种把显示的视频转成Image对象的方法:
using System.Windows.Forms;
//捕获视频成Image对象
public Image CatchVideo()
{

#region 导入API函数 [DllImport("avicap32.dll")]//包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口 public static extern IntPtr capCreateCaptureWindow(string lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hwndParent, int nID); /************参数说明************* * * 函数:capCreateCaptureWindow * * lpszWindowName:标识窗口的名称 * dwStyle:标识窗口风格 * x、y:标识窗口的左上角坐标 * nWidth、nHeight:标识窗口的宽度和高度 * hWnd:标识父窗口句柄 * nID:标识窗口ID * * 返回值:视频捕捉窗口句柄。 * ********************************/ [DllImport("AVICAP32.dll", CharSet = CharSet.Unicode)] public static extern bool capGetDriverDescription(int wDriverIndex, StringBuilder lpszName, int cbName, StringBuilder 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, int 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 bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPDRIVERCAPS lParam); [DllImport("User32.dll")] public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPTUREPARMS lParam); [DllImport("User32.dll")] public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPSTATUS 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); #endregion
可用来在VB,VC中驱动摄像头,进行静帧捕捉的DLL动态链接库(必须要有摄像头生成StillCap0000.bmp):将MyDll文件解压后把MyDll.dll与MyDll.lib一起拷入工程DEBUG目录中(为保险起见DEBUG的外层目录也拷贝一份吧),另有一个VC++6的测试工程test_Dll,已经考入相应DLL和LIB文件,可直接编译运行,VB只拷贝MyDll.dll与MyDll.lib VB2008 调用方法,在公共模块中声名: Public Declare Function CreateWnd Lib "MyDll" () As Double Public Declare Function ClearGraphs Lib "MyDll" () As Double Public Declare Function OnpStillCapture Lib "MyDll" (ByVal hwnd As Long) As Double Public Declare Function InitStillGraph Lib "MyDll" (ByVal hwnd As Long) As Double Public Declare Function CloseWnd Lib "MyDll" () As Double 在窗体上放置2个PictureBox控件,名字为:pic1,pic2 放置三个按键:名字为Btn1,Btn2,Btn3 Btn1为打开视频,调用代码: Private Sub Btn1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn1.Click InitStillGraph(pic1.Handle) '打开摄像头预览视频 end sub Btn2为截取视频保存为BMP,文件保存在应用程序路径下,调用代码: Private Sub Btn2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn2.Click OnpStillCapture(pic2.Handle) '截取预览视频一帧图像 end sub Btn3为截取视频保存为清除内存,调用代码: Private Sub Btn3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btn3.Click ClearGraphs() '退出前,完成内存清扫工 end sub VC调用方法: 在对话框上放置两个图像框,类型为位图,三个按键B1,B2,B3 定义全局函数引用: typedef HWND(* CreateWnd)(void);// typedef HRESULT(* InitStillGraph)(HWND hwnd); typedef void (* OnpStillCapture)(HWND hwnd); typedef int (* ClearGraphs)(); HINSTANCE glibsample; //如果定义成HANDLE类型,则出错 CreateWnd createwnd; InitStillGraph initStillGraph;//定义引用函数 OnpStillCapture onpStillCapture;//定义引用函数 ClearGraphs clearGraphs;//定义引用函数 用类向导为两个位图框建立控件(类型为Contorl)变量,m_p1,m_2 : 在窗口OnInitDialog()函数中调整图像框大小: // TODO: Add your specialized code here and/or call the base class m_p1.MoveWindow(0,0,200,200,true); m_p2.MoveWindow(210,0,200,200,true); glibsample=LoadLibrary("MyDll.dll"); //加载dll 在B1消息函数中: void 你的类::OnB1() { initStillGraph=(InitStillGraph)GetProcAddress(glibsample,"InitStillGraph"); (*initStillGraph)(m_p1.m_hWnd);//预览图像 } 在B2消息函数中: void 你的类::O
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值