原帖地址: http://blog.sina.com.cn/s/blog_4b677075010006da.html 表示感谢!
//*****************************************************************************
// Labwindows/cvi8.5 摄像头控制技术-实现屏幕截图、录像功能
// szlihongtao
// 2010-08-03
//*****************************************************************************
#include "windows.h"
#include "avicap32.h"
#include <cvirte.h>
#include <userint.h>
#include "cam.h"
//*****************************************************************************
// 设置所需要摄像头的常量
// WM_USER 这个常量在 winuser.h 这个文件中定义
// #define WM_USER 0x0400
//*****************************************************************************
#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_win; //定义面板句柄
static int panelHandle;
static int result; //定义摄像头句柄
//*****************************************************************************
// 主程序
//*****************************************************************************
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:
{
/*
handle_win
获得面板句柄,供操作系统windows使用
A number that can be cast to obtain the system-specific window handle for a top-level panel.
The actual type of the value is HWND.
The value is zero for child panels.
*/
GetPanelAttribute (panelHandle, ATTR_SYSTEM_WINDOW_HANDLE, &handle_win);
//获得屏幕中图像要显示的位置,即 PANEL_CANVAS_TV 的有关坐标参数
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_win,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 bitmapID; // int available; 定义BMP位图ID号
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);
GetBitmapFromFile (path, &bitmapID); //获得BMP位图ID
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;
}
DiscardBitmap (bitmapID); //删除BMP位图ID
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;
}
/*
capCreateCaptureWindowA
Declare capCreateCaptureWindow in "avicap32.dll" as "capCreateCaptureWindowA" ;
String lpszWindowName,; 视频窗口的名字
Long dwStyle ,; 样式
Long x ,; 左边距(相对于父窗口,一般为0)
Long y ,; 上边距(相对于父窗口,一般为0)
Long nWidth,; 视频窗口的宽度(注:此项并不会改变摄像头的分辨率,超出部分不会被刷新)
Long nHeight ,; 视频窗口的高度
Long hwndParent,; 父窗口句柄
Long nID 标识符(一般为0)
函数返回打开的句柄值。
这是VFW编程最基本的函数了,例如:
lwndC = capCreateCaptureWindowA("我的视频监视窗口", WS_CHILD , 0, 0, 160, 120, hwnd, 0)
--------------------------------------------------------------------------------------------------- */
只对你微笑 2022-8-27 23:16
用户377235 2016-6-28 12:39
用户414477 2012-5-16 12:21