C#利用VFW实现摄像头程序
最近在搞这个考试监控,找来VFW的资料,胡编乱凑而成。
VFW全称为Video for Windows,是微软提供的,内嵌windows系统。
首先定义一个VideoAPI类。
首先调用avicap32.dll
[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindow(byte[] strWindowName, int dwStyle, int x, int y, int width, int height, IntPtr hwdParent, int nID); [DllImport("avicap32.dll")]
public static extern bool capGetDriverDescription(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
再调用User32.dll
[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, string lParam);
再定义一堆消息。
//常量
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 + ;
public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + ;
public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + ;
public const int WM_CAP_SET_PREVIEW = WM_USER + ;
public const int WM_CAP_SET_PREVIEWRATE = WM_USER + ;
public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + ;
public const int WM_CAP_START = WM_USER;
public const int WM_CAP_SAVEDIB = WM_CAP_START + ;
public const int WM_CAP_SET_SCALE = WM_USER + ;
public const int WM_COPYTOCLIPBORAD = WM_USER + ;
public const int WM_CAP_SEQUENCE = WM_USER + ;
public const int WM_CAP_FILE_SET_CAPTURE_FILE = WM_USER + ;
public const int WM_CAP_STOP = WM_USER + ;
定义一个VideoClass,用于调用API,启动摄像头,关闭摄像头,保存图片等。
启动摄像头:
public bool StartWebcam()
{
byte[] lpszName = new byte[];
byte[] lpszVer = new byte[];
VideoAPI.capGetDriverDescription(, lpszName, , lpszVer, ); caphwnd = VideoAPI.capCreateCaptureWindow(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, , , this.width, this.height, this.controlhwnd, ); if (caphwnd == null)
{
return false;
} bool isconnect = VideoAPI.SendMessage(caphwnd,VideoAPI.WM_CAP_DRIVER_CONNECT,,);
if(isconnect == false)
{
VideoAPI.CloseHandle(caphwnd);
return false;
} if (VideoAPI.SendMessage(caphwnd, VideoAPI.WM_CAP_SET_PREVIEWRATE, , ) == false)
{
return false;
} if (VideoAPI.SendMessage(caphwnd, VideoAPI.WM_CAP_SET_PREVIEW, true, ) == false)
{
return false;
} if (VideoAPI.SendMessage(caphwnd, VideoAPI.WM_CAP_SET_SCALE, , ) == false)
{
return false;
} isstart = true;
return true;
}
关闭摄像头:
/// <summary>
/// 关闭视频设备
/// </summary>
/// <returns></returns>
public bool StopWebcam()
{
if (caphwnd != null)
{
isstart = false;
return VideoAPI.SendMessage(caphwnd, VideoAPI.WM_CAP_DRIVER_DISCONNECT, , );
}
else
return false;
}
截图:
public bool GrabImage(IntPtr hWndC, string path)
{
if (caphwnd != null)
return VideoAPI.SendMessage(caphwnd, VideoAPI.WM_CAP_SAVEDIB, , path);
else
return false;
} public bool SaveImage(string path)
{
return GrabImage(this.caphwnd, path);
}
截图并转换为jpg:
public void CopyToClipBorad()
{
VideoAPI.SendMessage(caphwnd, VideoAPI.WM_COPYTOCLIPBORAD, , );
} public System.Drawing.Image getCaptureImage()
{
System.Windows.Forms.IDataObject iData = System.Windows.Forms.Clipboard.GetDataObject();
System.Drawing.Image retImage = null;
if (iData != null)
{
if (iData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
{
retImage = (System.Drawing.Image)iData.GetData(System.Windows.Forms.DataFormats.Bitmap);
}
else if (iData.GetDataPresent(System.Windows.Forms.DataFormats.Dib))
{
retImage = (System.Drawing.Image)iData.GetData(System.Windows.Forms.DataFormats.Dib);
}
}
return retImage;
}
在调用类中写:
public void capture(string strname)
{
vc.CopyToClipBorad();
System.Drawing.Image img = vc.getCaptureImage();
img.Save(strname, System.Drawing.Imaging.ImageFormat.Jpeg);
}
附上视频类和控件:http://files.cnblogs.com/qiu2013/MyWebcam.zip
C#利用VFW实现摄像头程序的更多相关文章
- Jenkins简明入门(二) -- 利用Jenkins完成Python程序的build、test、deployment
大家可能还没搞清楚,Jenkins到底能做什么? 本节内容利用Jenkins完成python程序的build.test.deployment,让大家对Jenkins能做的事情有一个直观的了解. 本节内 ...
- Python 3 利用 Dlib 实现摄像头实时人脸检测和平铺显示
1. 引言 在某些场景下,我们不仅需要进行实时人脸检测追踪,还要进行再加工:这里进行摄像头实时人脸检测,并对于实时检测的人脸进行初步提取: 单个/多个人脸检测,并依次在摄像头窗口,实时平铺显示检测到的 ...
- 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本
建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...
- 利用msfvenom制作木马程序(你可以得到她的一切)
实验环境: 虚拟机:kali (攻击机) 192.168.1.2 虚拟机:windwos 2003 (靶机) 192.168.1.100 1. 制作木马 说明: -p payl ...
- C# 利用AForge进行摄像头信息采集
概述 AForge.NET是一个专门为开发者和研究者基于C#框架设计的,提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,机器人 ...
- 利用manifest文件对程序目录下的dll进行分类
1 背景 对于大部分的券商和机构投资者,只能通过有交易所交易系统接入资质的券商提供的柜台系统来进行现货交易.相对于期货市场,现货市场的柜台系统千差万别,接入协议有明文字符串.二进制数据和FIX协议等, ...
- php利用svn hooks将程序自动发布到测试环境
利用svn hooks将php程序自动发布到测试环境 复制仓库hooks目录下的post-commit.tmpl为post-commit cp post-commit.tmpl post-commit ...
- android利用数字证书对程序签名
签名的必要性 1. 防止你已安装的应用被恶意的第三方覆盖或替换掉. 2. 开发者的身份标识,签名可以防止抵赖等事件的发生. 开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同 ...
- android 利用数字证书对程序签名
签名的必要性 1. 防止你已安装的应用被恶意的第三方覆盖或替换掉. 2. 开发者的身份标识,签名可以防止抵赖等事件的发生. 开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样 ...
随机推荐
- Bootstarp学习教程(7) 表单
基本案例:“form-control”修饰的<input>.<textarea>和<select>元素都将被默认设置为width: 100%;表单控件包裹在&quo ...
- C++编程经验总结1
面向对象的精髓: 主函数其实就是对于类的元素和动作的重新组合来进行一项活动. 一个思想概念:程设是清楚的,完美的. 数学是清楚的,是完美的. 物理是有趣的,尤其是量子物理 生物是清楚的,尤其是基因 外 ...
- Mac openssl 和curl源码编译
1.先编译openssl, 下载源码后解压,终端进入源码目录,输入命令配置编译环境:./Configure darwin64-x86_64-cc 等待配置完成后,输入make 和make insta ...
- ReplaceChar
好吧,给个char的,替换单个字符.这样会快一些吧,这个是置换,连长度都不用了 bool ReplaceChar(char *str,const char src, const char dst){ ...
- 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final
◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...
- ABAP 调用远程rfc
ABAP 调用rfc DESTINATION附加项后面接的是远程目标名称,该目标在事务SM59中设定,其中包含连接和登录远程系统所需的全部参数信息.如果调用的就是本机的RFC目标,则DESTINATI ...
- linux安装openldap步骤
目录 虚拟机环境:centos 7 一.环境准备 1.关闭 selinux firewalld 临时: setenforce 0 永久: vi /etc/sysconfig/selinux SELI ...
- JavaScript---ECMA对象
1.对象的概念及分类 1.1 ECMAScript中没有类,但定义了“对象”,逻辑上等价于其他程序设计语言中的类. var o = new Object(); 1.2 本地对象(native obje ...
- html之table&select不为人知的操作
table标签和其它标签不一样,他有属性和方法! table属性: rows 可以得到table的row集合 cells 得到table所有单元格 table方法: insertR ...
- Python全栈day 05
Python全栈day 05 一.数据类型补充 1. int py2和py3的2种区别 py2有int和long,int的取值范围为-2^31~2^31-1,超出范围自动转为long,长整型. py2 ...