加载中…
个人资料
skyun
skyun
  • 博客等级:
  • 博客积分:0
  • 博客访问:112,505
  • 关注人气:12
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

[转+修正]一个简单的摄像头程序

(2010-11-11 18:18:57)
标签:

it

分类: 编程

最近要做一个与摄像头编程有关的项目演示,在网上找了一些方法,主要有两种,一种是用DirectShow开发包,另一种就是用vfw开发包,感觉vfw比较简单,而且在网上找到一个很简短的vfw的程序,因此打算采用这种方式来做项目开发。

 

本文最后是网上找到的代码,能成功编译,但运行之后并没有显示图像,于是只有单步调试,看看整个创建捕获窗口的过程,发现直到执行到下面这条语句都还正常

   capDriverConnect(ghWndCap, 0); 

其返回值是1,MSDN上对capDriverGetCaps函数返回值的描述是:

Returns TRUE if successful or FALSE if the specified capture driver cannot be connected to the capture window.

说明捕获窗口能成功连接到捕获设备。

 

但是紧接着下一行代码:

   capDriverGetCaps(ghWndCap, &gCapDriverCaps, sizeof(CAPDRIVERCAPS));

其返回值是0,MSDN上对capDriverGetCaps函数返回值的描述是:

Returns TRUE if successful or FALSE if the capture window is not connected to a capture driver.

也就是捕获窗口没有连接到捕获设备。

 

这跟前一条语句不是矛盾吗

前一条语句让捕获窗口和捕获设备成功连接

紧接着下一条语句就返回错误,且原因是捕获窗口和捕获设备没有连接上

百思不得其解,最后查看了一下ghWndCap这个变量,发现在执行完前面一条语句后,这个变量的值改变了,也就是执行第二条语句时ghWndCap的值已经不对了,于是我在执行前语句之前,先将ghWndCap的值保存到一个变量中,在执行后一条语句之前,再将这个值赋给ghWndCap,居然就能成功的捕捉到图像了。

 

 

#include <windows.h>
#include <stdio.h>
#include <vfw.h>
#pragma comment(lib,"vfw32.lib")

HWND ghWndCap ; //捕获窗的句柄 
CAPDRIVERCAPS gCapDriverCaps ; //视频驱动器的能力 
CAPSTATUS gCapStatus ; //捕获窗的状态 
char szCaptureFile[] = "MYCAP.AVI";
char gachBuffer[20];

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

LRESULT CALLBACK StatusCallbackProc(HWND hWnd,int nID,LPSTR lpStatusText)
{
 if(!ghWndCap)return FALSE;//获得捕获窗的状态
 capGetStatus(ghWndCap,&gCapStatus,sizeof(CAPSTATUS));//更新捕获窗的大小
 SetWindowPos(ghWndCap,NULL,0,0,gCapStatus.uiImageWidth,gCapStatus.uiImageHeight,SWP_NOZORDER|SWP_NOMOVE);
 if(nID==0){//清除旧的状态信息
  SetWindowText(ghWndCap,(LPSTR)"hello");
  return (LRESULT)TRUE;
 }//显示状态ID和状态文本
 wsprintf(gachBuffer,"Status# %d: %s",nID,lpStatusText);
 SetWindowText(ghWndCap,(LPSTR)gachBuffer);
 return (LRESULT)TRUE;
}
LRESULT CALLBACK ErrorCallbackProc(HWND hWnd,int nErrID,LPSTR lpErrorText)
{
 if(!ghWndCap)return FALSE;
 if(nErrID==0)return TRUE;//清除旧的错误
 wsprintf(gachBuffer,"Error# %d",nErrID);//显示错误标识和文本
 MessageBox(hWnd, lpErrorText, gachBuffer,MB_OK | MB_ICONEXCLAMATION); 
 return (LRESULT) TRUE;
}

LRESULT CALLBACK FrameCallbackProc(HWND hWnd,LPVIDEOHDR lpVHdr)
{
 FILE *fp;
 fp=fopen("caram.dat","w");
 if(!ghWndCap)return FALSE;//假设fp为一打开的.dat文件指针
 fwrite(lpVHdr->lpData,1,lpVHdr->dwBufferLength,fp);
 return (LRESULT)TRUE;
}


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
 static TCHAR szAppName[]=TEXT("HelloWin");
 HWND hwnd;
 MSG msg;
 WNDCLASS wndclass;
 wndclass.style=CS_HREDRAW|CS_VREDRAW;
 wndclass.lpfnWndProc=WndProc;
 wndclass.cbClsExtra=0;
 wndclass.cbWndExtra=0;
 wndclass.hInstance=hInstance;
 wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
 wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
 wndclass.lpszMenuName=NULL;
 wndclass.lpszClassName=szAppName;
 if(!RegisterClass(&wndclass))
 {
  MessageBox(NULL,TEXT("This program requires WindowsNT!"),szAppName,MB_ICONERROR);
  return 0;
 }


 hwnd=CreateWindow(szAppName,TEXT("The Hello Program"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
 ShowWindow(hwnd,iCmdShow);
 UpdateWindow(hwnd);


 while(GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }
 return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 RECT rect;
 switch(message)
 {
 case WM_CREATE:
  {
   ghWndCap=capCreateCaptureWindow((LPSTR)"Capture  Window",WS_CHILD|WS_VISIBLE,0,0,300,600,(HWND)hwnd,(int)0);
   capSetCallbackOnError(ghWndCap,(FARPROC)ErrorCallbackProc);
   capSetCallbackOnStatus(ghWndCap,(FARPROC)StatusCallbackProc);
   capSetCallbackOnFrame(ghWndCap,(FARPROC)FrameCallbackProc);
   capDriverConnect(ghWndCap,0); // 将捕获窗同驱动器连接
   //获得驱动器的能力,相关的信息放在结构变量gCapDriverCaps中
   capDriverGetCaps(ghWndCap,&gCapDriverCaps,sizeof(CAPDRIVERCAPS));
   capPreviewRate(ghWndCap, 66); // 设置Preview模式的显示速率
   capPreview(ghWndCap, TRUE); //启动Preview模式
   if(gCapDriverCaps.fHasOverlay) //检查驱动器是否有叠加能力
    capOverlay(ghWndCap,TRUE); //启动Overlay模式
   if(gCapDriverCaps.fHasDlgVideoSource)capDlgVideoSource(ghWndCap); //Video source 对话框
   if(gCapDriverCaps.fHasDlgVideoFormat)capDlgVideoFormat(ghWndCap); // Video format 对话框
   if(gCapDriverCaps.fHasDlgVideoDisplay)capDlgVideoDisplay(ghWndCap); // Video display 对话框
   capFileSetCaptureFile( ghWndCap, szCaptureFile); //指定捕获文件名
   capFileAlloc(ghWndCap, (1024L * 1024L * 5)); //为捕获文件分配存储空间
   capCaptureSequence(ghWndCap); //开始捕获视频序列
   capGrabFrame(ghWndCap); //捕获单帧图像
  }

  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hwnd,&ps);
  GetClientRect(hwnd,&rect);
  DrawText(hdc,TEXT("Hello,Windows98!"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  EndPaint(hwnd,&ps);
  return 0;
 case WM_DESTROY:
  {
   capSetCallbackOnStatus(ghWndCap,NULL);
   capSetCallbackOnError(ghWndCap,NULL); 
   capSetCallbackOnFrame(ghWndCap,NULL);
   capCaptureAbort(ghWndCap);//停止捕获 
   capDriverDisconnect(ghWndCap); //将捕获窗同驱动器断开 
   PostQuitMessage(0);
  }
  return 0;
 }
 return DefWindowProc(hwnd,message,wParam,lParam);
}

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有