标题: [原创]基于LabWindows/CVI的摄像头控制技术--实现屏幕截图、录像功能 [打印本页]
作者: wangjianxin2001 时间: 2006-11-20 17:26 标题: [原创]基于LabWindows/CVI的摄像头控制技术--实现屏幕截图、录像功能
我们都知道,LabWindows/CVI的强大功能实际上不只是在测控领域,在其它方面,也显示着无与伦比的优势。 你的电脑有没有摄像头?看到别人用QQ玩视屏你会不会去想怎么实现的?
一般来说,所有的摄像头都会包括一个AVICAP32.DLL动态链接库文件,而动态库里面必有capCreateCaptureWindow和capCreateCaptureWindowA这两个函数,我们就是利用这些函数实现图像采集的!
这里介绍使用AVICAP32.DLL就可轻松的实现对摄像头编程,如果再加上你的网络编程水平,实现一个视屏聊天就不成什么问题了。如果电脑没有摄像头,但又想看看程序的效果,可以么?呵呵,当然可以,找个虚拟摄像头就可以搞定了,大家可以试试“SoftCam”这个软件,它是一个名副其实的软件摄像机,能模拟成为“真实的”摄像机,提醒一下各位,大家可不要用这个东东用在QQ,MSN等聊天软件上欺骗MM或GG啊。
本例能实现图片的保存,浏览以及录像功能,在界面上都能显示出来,大家仔细瞧瞧吧!
界面如下:
图中的景像就是我的实验室,情况有点糟糕,哈哈,还能凑合着过!
代码如下:
#include "windows.h"
#include "avicap32.h"
#include
#include
#include "cam.h"
//设置所需要摄像头的常量
#define WM_CAP_START WM_USER //开始
#define WM_CAP_STOP WM_CAP_START + 68 //停止
#define WM_CAP_DRIVER_CONNECT WM_CAP_START + 10 //连接
#define WM_CAP_DRIVER_DISCONNECT WM_CAP_START + 11 //断开
#define WM_CAP_SAVEDIB WM_CAP_START + 25
#define WM_CAP_GRAB_FRAME WM_CAP_START + 60
#define WM_CAP_SEQUENCE WM_CAP_START + 62
#define WM_CAP_FILE_SET_CAPTURE_FILEA WM_CAP_START + 20 //保存至文件
#define WM_CAP_SEQUENCE_NOFILE WM_CAP_START + 63
#define WM_CAP_SET_OVERLAY WM_CAP_START + 51
#define WM_CAP_SET_PREVIEW WM_CAP_START + 50
#define WM_CAP_SET_CALLBACK_VIDEOSTREAM WM_CAP_START +6
#define WM_CAP_SET_CALLBACK_ERROR WM_CAP_START +2
#define WM_CAP_SET_CALLBACK_STATUSA WM_CAP_START +3
#define WM_CAP_SET_CALLBACK_FRAME WM_CAP_START +5
#define WM_CAP_SET_SCALE WM_CAP_START+ 53
#define WM_CAP_SET_PREVIEWRATE WM_CAP_START+ 52
#define WM_CAP_COPYDIB WM_CAP_START + 30 //复制图片
//定义面板句柄
static int handle;
//定义摄像头句柄
static int result;
static int panelHandle;
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "cam.uir", PANEL)) < 0)
return -1;
DisplayPanel (panelHandle);
RunUserInterface ();
DiscardPanel (panelHandle);
return 0;
}
//退出按钮
int CVICALLBACK QuitCallback (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
QuitUserInterface (0);
break;
}
return 0;
}
//开始按钮
int CVICALLBACK startCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int width;
int height;
int top;
int left;
switch (event)
{
case EVENT_COMMIT:
//获得面板句柄
GetPanelAttribute (panelHandle, ATTR_SYSTEM_WINDOW_HANDLE, &handle);
//获得屏幕中图像要显示的位置
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_LEFT, &left);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_TOP, &top);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, &height);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, &width);
//打开摄像头
result = capCreateCaptureWindowA("",WS_CHILD | WS_VISIBLE ,left,top,width,height,handle,0);
//设置摄像头函数
SendMessage((HWND)result, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);
SendMessage((HWND)result, WM_CAP_SET_CALLBACK_ERROR, 0, 0);
SendMessage((HWND)result, WM_CAP_SET_CALLBACK_STATUSA, 0, 0);
SendMessage((HWND)result, WM_CAP_DRIVER_CONNECT, 0, 0);
SendMessage((HWND)result, WM_CAP_SET_SCALE, 1, 0);
SendMessage((HWND)result, WM_CAP_SET_PREVIEWRATE, 66, 0);
SendMessage((HWND)result, WM_CAP_SET_OVERLAY, 1, 0);
SendMessage((HWND)result, WM_CAP_SET_PREVIEW, 1, 0);
break;
}
return 0;
}
//停止按钮
int CVICALLBACK stopCB (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
if (result != 0)
{
//断开连接
SendMessage((HWND)result, WM_CAP_DRIVER_DISCONNECT, 0, 0);
}
break;
}
return 0;
}
//保存BMP按钮
int CVICALLBACK recordbmp (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
// int available;
//定义BMP位图ID号
int bitmapID;
//定义文件存储路径
char path[MAX_PATHNAME_LEN];
//定义静态变量,设置循环次数
static int i;
switch (event)
{
case EVENT_COMMIT:
/* 此代码为将图片存入剪切板
if (result != 0)
{
SendMessage((HWND)result, WM_CAP_GRAB_FRAME, 0, 0);
SendMessage((HWND)result, WM_CAP_COPYDIB, 0, 0);
ClipboardGetBitmap (&bitmapID, &available);
if (available ==1)
{
CanvasClear (panelHandle, PANEL_CANVAS, VAL_ENTIRE_OBJECT);
CanvasDrawBitmap (panelHandle, PANEL_CANVAS, bitmapID, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);
}
DiscardBitmap (bitmapID);
}
*/
//保存位图
if (FileSelectPopup ("", "*.bmp", "*.bmp", "保存", VAL_SAVE_BUTTON, 0, 0, 1, 1, path) > 0)
{
SendMessage((HWND)result,WM_CAP_SAVEDIB,0,(LPARAM)path);
//获得BMP位图ID
GetBitmapFromFile (path, &bitmapID);
switch (i)
{
//设置三个位图浏览器
case 0:
CanvasDrawBitmap (panelHandle, PANEL_CANVAS_SNAP0, bitmapID, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);
break;
case 1:
CanvasDrawBitmap (panelHandle, PANEL_CANVAS_SNAP1, bitmapID, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);
break;
case 2:
CanvasDrawBitmap (panelHandle, PANEL_CANVAS_SNAP2, bitmapID, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);
break;
}
//删除BMP位图ID
DiscardBitmap (bitmapID);
//循环累加,共三次,三次之后回零
i++;
if (i == 3)
{
i = 0;
}
}
break;
}
return 0;
}
//开始录像按钮
int CVICALLBACK recordstream (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
char path[MAX_PATHNAME_LEN];
switch (event)
{
case EVENT_COMMIT:
//保存录像
if (FileSelectPopup ("", "*.avi", "*.avi", "保存", VAL_SAVE_BUTTON, 0, 0, 1, 1, path) > 0)
{
SendMessage((HWND)result,WM_CAP_FILE_SET_CAPTURE_FILEA,0,(LPARAM)path);
SendMessage((HWND)result, WM_CAP_SEQUENCE, 0, 0);
}
break;
}
return 0;
}
//停止录像按钮
int CVICALLBACK stopstream (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
SendMessage((HWND)result, WM_CAP_STOP, 0, 0);
break;
}
return 0;
}
//显示制式设置
int CVICALLBACK method (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
int kind;
int width;
int height;
int top;
int left;
switch (event)
{
case EVENT_COMMIT:
//获得制式种类
GetCtrlVal (panelHandle, PANEL_RING, &kind);
switch (kind)
{
case 0:
//160*120制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 160);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 120);
break;
case 1:
//1176*144制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 176);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 144);
break;
case 2:
//320*240制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 320);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 240);
break;
case 3:
//352*288制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 352);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 288);
break;
case 4:
//1默认制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 592);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 333);
break;
}
//获得屏幕中图像要显示的位置
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_LEFT, &left);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_TOP, &top);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, &height);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, &width);
//重新定位
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_TOP, (333-height)/2+55);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_LEFT, (592-width)/2+53);
//断开连接
SendMessage((HWND)result, WM_CAP_DRIVER_DISCONNECT, 0, 0);
//调用开始按钮事件
startCB(panel, PANEL_CANVAS_TV, EVENT_COMMIT, NULL, 0, 0);
break;
}
return 0;
}
作者: 蜡人 时间: 2006-11-21 16:21
挺专业的,非常想看看“庐山真面目”
能给我把做好的发过来吗?学习学习
candle-ren@sohu.com
万分感谢!
作者: yingx616 时间: 2009-10-20 13:29
楼主太强大了,基于labwindows/cvi的USB摄像头控制系统就是我的毕业设计啊,顶。我在迷茫中看到了一点曙光,谢谢
作者: tbgkj2010 时间: 2010-3-30 14:36
这里介绍使用AVICAP32.DLL就可轻松的实现对摄像头编程,如果再加上你的网络编程水平,实现一个视屏聊天就不成什么问题了。如果电脑没有摄像头,但又想看看程序的效果,可以么?呵呵,当然可以,找个虚拟摄像头就可以搞定了,大家可以试试“SoftCam”这个软件,它是一个名副其实的软件摄像机,能模拟成为“真实的”摄像机,提醒一下各位,大家可不要用这个东东用在QQ,MSN等聊天软件上欺骗MM或GG啊。
//160*120制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 160);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 120);
break valve testing machine;
case 1:
//1176*144制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 176);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 144);
break;
case 2:
//320*240制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 320);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 240);
break;
case 3:
//352*288制式
SetCtrlAttribute (panelHandle,Valve testing machine PANEL_CANVAS_TV, ATTR_WIDTH, 352);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 288);
break;
case 4:
//1默认制式
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, 592);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, 333);
break;
}
//获得屏幕中图像要显示的位置
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_LEFT, &left);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_TOP, &top);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_HEIGHT, &height);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_WIDTH, &width);
//重新定位
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_TOP, (333-height)/2+55);
SetCtrlAttribute (panelHandle, PANEL_CANVAS_TV, ATTR_LEFT, (592-width)/2+53);
作者: 北风如歌 时间: 2011-10-5 22:46
哎呀呀,牛叉
作者: 星雨水火 时间: 2014-7-17 18:07
如何实现在面板中实时显示两个摄像头所采集的数据
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) |
Powered by Discuz! 7.0.0 |