MFC vfw视频捕获

来源:互联网 发布:微盘交易源码 阴极铜 编辑:程序博客网 时间:2024/05/18 21:50
// VideoImage_lzyView.cpp : implementation of the CVideoImage_lzyView class//#include "stdafx.h"// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail// and search filter handlers and allows sharing of document code with that project.#ifndef SHARED_HANDLERS#include "VideoImage_lzy.h"#endif#include "VideoImage_lzyDoc.h"#include "VideoImage_lzyView.h"#ifdef _DEBUG#define new DEBUG_NEW#endif//全局变量static DWORD AVIwidth = 639;//640 480 溢出错误;639 479及以下就没有错误static DWORD AVIheight = 479;//但是SDK里面正常  http://blog.csdn.net/lzy2014/article/details/27558901HBITMAP hBmpScene;HDC hdcScene = NULL;CDC* pDC;// CVideoImage_lzyViewIMPLEMENT_DYNCREATE(CVideoImage_lzyView, CView)BEGIN_MESSAGE_MAP(CVideoImage_lzyView, CView)// Standard printing commandsON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)ON_COMMAND(IDM_BMP_CAP, &CVideoImage_lzyView::OnBmpCap)ON_COMMAND(IDM_BMP_SAVE, &CVideoImage_lzyView::OnBmpSave)//ON_WM_SIZE()END_MESSAGE_MAP()// CVideoImage_lzyView construction/destructionCVideoImage_lzyView::CVideoImage_lzyView(){// TODO: add construction code herehWndCap = NULL;//构造函数中将其初始化}CVideoImage_lzyView::~CVideoImage_lzyView(){}BOOL CVideoImage_lzyView::PreCreateWindow(CREATESTRUCT& cs){// TODO: Modify the Window class or styles here by modifying//  the CREATESTRUCT csreturn CView::PreCreateWindow(cs);}// CVideoImage_lzyView drawingvoid CVideoImage_lzyView::OnDraw(CDC* /*pDC*/){CVideoImage_lzyDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;// TODO: add draw code for native data here}// CVideoImage_lzyView printingBOOL CVideoImage_lzyView::OnPreparePrinting(CPrintInfo* pInfo){// default preparationreturn DoPreparePrinting(pInfo);}void CVideoImage_lzyView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add extra initialization before printing}void CVideoImage_lzyView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){// TODO: add cleanup after printing}// CVideoImage_lzyView diagnostics#ifdef _DEBUGvoid CVideoImage_lzyView::AssertValid() const{CView::AssertValid();}void CVideoImage_lzyView::Dump(CDumpContext& dc) const{CView::Dump(dc);}CVideoImage_lzyDoc* CVideoImage_lzyView::GetDocument() const // non-debug version is inline{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CVideoImage_lzyDoc)));return (CVideoImage_lzyDoc*)m_pDocument;}#endif //_DEBUG// CVideoImage_lzyView message handlers//视频捕获函数void CVideoImage_lzyView::OnBmpCap(){// TODO: Add your command handler code here//获取客户区大小CRect clientRect;GetClientRect(&clientRect);//创建图像采集窗口hWndCap = capCreateCaptureWindow(TEXT("采集图像"), WS_CHILD | WS_VISIBLE, 0, 0,AVIwidth, AVIheight, m_hWnd, 1);//注意最后一个参数if (! hWndCap){MessageBox(TEXT("图像采集窗口创建失败!"));return;}BITMAPINFO bmpInfo;HGDIOBJ hGDIObj;//DIB结构体的各种属性设置  ZeroMemory(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER));  bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  bmpInfo.bmiHeader.biBitCount = 24;  bmpInfo.bmiHeader.biWidth = AVIwidth;  bmpInfo.bmiHeader.biHeight = AVIheight;  bmpInfo.bmiHeader.biPlanes = 1;  bmpInfo.bmiHeader.biClrUsed = 0;  bmpInfo.bmiHeader.biClrImportant = 0;  bmpInfo.bmiHeader.biSizeImage = AVIwidth * AVIheight * bmpInfo.bmiHeader.biBitCount / 8;  //创建应用程序可以直接写入的、与设备无关的位图(DIB) pDC = this->GetDC();hdcScene = CreateCompatibleDC(pDC->m_hDC);  hBmpScene = CreateDIBSection(hdcScene, &bmpInfo, DIB_RGB_COLORS, NULL, 0, 0);  hGDIObj = SelectObject(hdcScene, hBmpScene);//设置回调函数capSetCallbackOnFrame(hWndCap, &FrameCallbackProc);//连接视频采集设备if (! capDriverConnect(hWndCap, 0))//注意:第二个参数是摄像头索引号(含有多个摄像头需注意);第二个参数  调试!!!!!!!{MessageBox(TEXT("视频采集设备连接失败!"));return;}//设置视频预览的图像大小 和 频率capPreviewRate(hWndCap, 30);capPreviewScale(hWndCap, TRUE);//第二个参数  调试!!!!!!!SelectObject(hdcScene, hGDIObj);  DeleteObject(hBmpScene); DeleteDC(hdcScene);}//图像保存函数void CVideoImage_lzyView::OnBmpSave(){// TODO: Add your command handler code hereif (! capFileSaveDIB(hWndCap, TEXT("save.bmp"))){MessageBox(TEXT("图像保存失败!"));return;}}LRESULT CVideoImage_lzyView::FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr){long cB, cG, cR;  long X, Y;long OutputWidth = AVIwidth * 3;  long InputWidth = AVIwidth * 3;BYTE BmpByte[1920*480];for (Y = 1; Y <= AVIheight; Y++)      {          for (X = 1; X <= AVIwidth; X++)          {              cB = lpVHdr->lpData[((AVIheight-Y)*InputWidth)+(X*3)];              cG = lpVHdr->lpData[((AVIheight-Y)*InputWidth)+(X*3)+1];              cR = lpVHdr->lpData[((AVIheight-Y)*InputWidth)+(X*3)+2];              BmpByte[((Y-1)*OutputWidth)+(X*3)]=cB;              BmpByte[((Y-1)*OutputWidth)+(X*3)+1]=cG;              BmpByte[((Y-1)*OutputWidth)+(X*3)+2]=cR; /*if (X == 160 && Y == 120){system("pause");//查看数据是否有变化}*/        }    } long i = sizeof(BmpByte);long i2 = SetBitmapBits(hBmpScene, sizeof(BmpByte), BmpByte);//成功后,返回值表示字节数;失败为0.    BitBlt(pDC->m_hDC, 0, 0, AVIwidth, AVIheight, hdcScene, 0, 0, SRCCOPY);//一个现象就是,视频不动,但是不停地改变窗口大小(拖动窗口右下角)时,视频动了;//说明需要重绘,invalidate//但是,static函数(回调函数)里面不能直接调用Invalidate函数//需要通过GetActiveWindow  FindWindow 等等获取view类窗口句柄GetActiveWindow()->Invalidate(TRUE);//成功后,闪屏厉害;要用到双缓冲    return 0;}


都是在CView类里面   

在菜单里面增加的两个菜单命令响应函数(视类)  

头文件如下:

只增加了窗口句柄hWndCap和回调函数

// VideoImage_lzyView.h : interface of the CVideoImage_lzyView class//#pragma onceclass CVideoImage_lzyView : public CView{protected: // create from serialization onlyCVideoImage_lzyView();DECLARE_DYNCREATE(CVideoImage_lzyView)// Attributespublic:CVideoImage_lzyDoc* GetDocument() const;// Operationspublic:// Overridespublic:virtual void OnDraw(CDC* pDC);  // overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);// Implementationpublic:virtual ~CVideoImage_lzyView();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:// Generated message map functionsprotected:DECLARE_MESSAGE_MAP()private:HWND hWndCap;public:afx_msg void OnBmpCap();afx_msg void OnBmpSave();static LRESULT FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr);//afx_msg void OnSize(UINT nType, int cx, int cy);};#ifndef _DEBUG  // debug version in VideoImage_lzyView.cppinline CVideoImage_lzyDoc* CVideoImage_lzyView::GetDocument() const   { return reinterpret_cast<CVideoImage_lzyDoc*>(m_pDocument); }#endif

还需要优化变量,如何安排或者抽象到类。


0 0
原创粉丝点击