缘由:作为一枚还没出学校的实习僧,进入公司接手的第一个项目,没人带,没用过CVI,而且公司还没人做过,幸好作为一个现代人还有互联网。从一无所知接手到写完这个测试程序,接近花了我3周左右的时间。我认为很有意义,实际项目要比这复杂,这只是其中一个功能而已。
其中两人的博客的资料对我来说较为重要,影响着整个编程。
1. 小信:基于LabWindows/CVI的摄像头控制技术--实现屏幕截图、录像功能 博客源地址:http://blog.sina.com.cn/s/blog_4b677075010006da.html
2. 醉囧里囧梦囧回:LabWindows/CVI入门之第六章:综合实例:远程监控系统 博客源地址:http://blog.sina.com.cn/s/blog_6373e9e60101cetk.html
(我有部分是借鉴醉囧里囧梦囧回的编程思路,但有不一样,他所用的是通过网页实现图像显示,而我是通过TCP服务端和客户端实现图像显示)
一、任务描述:
1.图像采集(在CVI摄像头控制技术里有较为详细的介绍)
2.图像传输(将图像数据通过Base64转码,将Base64编码通过TCP有客户端发送给服务端)
3.图像接收并显示(将接收数据,通过Base64解码,转换为图像数据保存显示)
注:因为我在查询图片转发时,最开始查询到的方法是直接将图片转换为二进制数据发送就行,但实际操作中数据转发和接收到的数据转成图片时,图片不能正常生成。所以最好选择base64转码解决这个问题。
界面效果:
二、系统详细设计:
(1)图像采集
我所用USB摄像头为免驱摄像头,“免驱”的意思并不是说这种摄像头不需要驱动即可运行,而是因为目前市面上主流的操作系统中已经包含了该摄像头所需要的驱动程序,当摄像头连接计算机后无需额外安装驱动程序。
考虑到普通摄像头加载驱动时均加载avicap32.dll,而且使用AVICAP32开发复杂度较低,所以就才用AVICAP32进行开发。需要在程序中引入avicap32的动态链接库。
UI设计:
1)摄像头初始化打开:
int Display_width;
int Display_height;
int Display_top;
int Display_left;
int i;
//获得面板句柄,用于在调用摄像头函数时,需要使用的句柄handle
GetPanelAttribute (panelHandle, ATTR_SYSTEM_WINDOW_HANDLE, &handle);
//获得屏幕中图像要显示的位置
GetCtrlAttribute (panelHandle, PANEL_CANVAS_DISPLAY, ATTR_LEFT, &Display_left);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_DISPLAY, ATTR_TOP, &Display_top);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_DISPLAY, ATTR_HEIGHT, &Display_height);
GetCtrlAttribute (panelHandle, PANEL_CANVAS_DISPLAY, ATTR_WIDTH, &Display_width);
//打开摄像头
result = capCreateCaptureWindowA("",WS_CHILD | WS_VISIBLE ,Display_left,Display_top,Display_width,Display_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);
for(i=0;i<3;i++)
{
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);
注:在开启摄像头中出现过摄像头指示灯亮,但界面上一片漆黑,没有图像。原因为驱动没有调用。多调用几次图像就会出现。也就是源代码中的:SendMessage((HWND)result, WM_CAP_DRIVER_CONNECT, 0, 0);
2)截图操作
int CVICALLBACK CapOneSnap (int handle, int result, int message, unsigned int* wParam, unsigned int* lParam, void* callbackData)
{
char bmpFilePath[MAX_PATHNAME_LEN ]="";
char jpgFilePath[MAX_PATHNAME_LEN ]="";
int bitmap_ID;
switch(message)
{
case (WM_USER+1009):
//do some things.
GetDir(bmpFilePath);
GetDir(jpgFilePath);
sprintf(bmpFilePath,"%s\\%u.bmp",bmpFilePath,(unsigned long)(*wParam));
sprintf(jpgFilePath,"%s\\%u.jpg",jpgFilePath,(unsigned long)(*wParam));
SendMessage((HWND)result,WM_CAP_SAVEDIB,0,(LPARAM)bmpFilePath);
GetBitmapFromFile ( bmpFilePath , &bitmap_ID );
SaveBitmapToJPEGFile(bitmap_ID,jpgFilePath,JPEG_DC