VMR_Capture.cpp
上传用户:czshopping
上传日期:2022-05-22
资源大小:5430k
文件大小:19k
源码类别:

视频捕捉/采集

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////
  2. //
  3. //  This class is designed to provide simple interface for 
  4. //  simultaneous Video Capture & Preview using DirectShow
  5. //
  6. //////////////////////////////////////////////////////////////////////
  7. //
  8. // References: MS DirectShow Samples
  9. //
  10. //
  11. //////////////////////////////////////////////////////////////////////
  12. //
  13. // This class was written by Sagar K.R . 
  14. //  Use of this class is not restricted in any
  15. // way whatsoever.Please report the bugs to krssagar@firsteccom.co.kr
  16. //
  17. // Special thanks to all the members at The Code Project! 
  18. // (www.codeproject.com)
  19. //
  20. //////////////////////////////////////////////////////////////////////
  21. // VMR_Capture.cpp: implementation of the CVMR_Capture class.
  22. //
  23. //////////////////////////////////////////////////////////////////////
  24. #include "stdafx.h"
  25. #include "VMR_Capture.h"
  26. #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
  27. int iMinOld=0,iMinNew=0;
  28. //////////////////////////////////////////////////////////////////////
  29. // Construction/Destruction
  30. //////////////////////////////////////////////////////////////////////
  31. CVMR_Capture::CVMR_Capture()
  32. {
  33. CoInitialize(NULL);
  34. m_pGB = NULL;
  35. m_pMC = NULL;
  36. m_pME = NULL;
  37. m_pWC = NULL;
  38. m_pDF =NULL;
  39. m_pCamOutPin =NULL;
  40. m_pFrame=NULL;
  41. m_nFramelen=0;
  42. m_psCurrent=Stopped;
  43. m_iHeight=240;
  44. m_iWidth=320; 
  45. lpVideo=this;
  46. }
  47. CVMR_Capture::~CVMR_Capture()
  48. {
  49. CloseInterfaces();
  50. CoUninitialize( );
  51. m_MoveTrace.Uninitialize();
  52. }
  53. HRESULT CVMR_Capture::Init(int iDeviceID,HWND hWnd, int iWidth, int iHeight)
  54. {
  55. HRESULT hr;
  56. // Get the interface for DirectShow's GraphBuilder
  57.     hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
  58.                          IID_IGraphBuilder, (void **)&m_pGB);
  59.     if(SUCCEEDED(hr))
  60.     {
  61.         // Create the Video Mixing Renderer and add it to the graph
  62.         InitializeWindowlessVMR(hWnd);        
  63. // Bind Device Filter.  We know the device because the id was passed in
  64. if(!BindFilter(iDeviceID, &m_pDF))
  65. return S_FALSE;
  66. hr=m_pGB->AddFilter(m_pDF, L"Video Capture");
  67. if (FAILED(hr))
  68. return hr;
  69. CComPtr<IEnumPins> pEnum;
  70. m_pDF->EnumPins(&pEnum);
  71. hr = pEnum->Reset();
  72. hr = pEnum->Next(1, &m_pCamOutPin, NULL); 
  73.         // QueryInterface for DirectShow interfaces
  74.         hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
  75.         hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);     
  76. // Have the graph signal event via window callbacks for performance
  77.         //hr = pME->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHNOTIFY, 0);
  78. hr = InitVideoWindow(hWnd,iWidth, iHeight);
  79. m_nFramelen=iWidth*iHeight*3;
  80. m_pFrame=(BYTE*) new BYTE[m_nFramelen];
  81.         
  82. // Run the graph to play the media file
  83. m_psCurrent=Stopped;
  84.         
  85. hr = m_pGB->Render(m_pCamOutPin);
  86. hr = m_pMC->Run();
  87. m_psCurrent=Running;
  88.         
  89. }
  90. // m_hCapWnd=hWnd;
  91. ///////////////////////////////////////
  92. m_hParentWnd=hWnd;
  93. m_hCapWnd=hWnd;
  94. // m_hCapWnd= capCreateCaptureWindow(
  95. // (LPSTR)"Face Video Capture Window", WS_CHILD|WS_VISIBLE,
  96. // 0, 0,m_iWidth,m_iHeight,
  97. //  hwndParent, nCapWndID );
  98. m_pDC=CWnd::FromHandle(m_hParentWnd)->GetDC();
  99. if (m_MemDC.GetSafeHdc()==NULL)
  100. {
  101. m_MemDC.CreateCompatibleDC(m_pDC);
  102. }
  103. m_Bitmap.CreateCompatibleBitmap(m_pDC,m_iWidth,m_iHeight);
  104. m_MoveTrace.Initialize(320, 240,3,3);
  105. m_bStorageData=FALSE;
  106. //////////////////////////////////////
  107. return hr;
  108. }
  109. HRESULT CVMR_Capture::InitializeWindowlessVMR(HWND hWnd)
  110. {
  111.     IBaseFilter* pVmr = NULL;
  112.     // Create the VMR and add it to the filter graph.
  113.     HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
  114.                                   CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
  115.     if (SUCCEEDED(hr)) 
  116.     {
  117.         hr = m_pGB->AddFilter(pVmr, L"Video Mixing Renderer");
  118.         if (SUCCEEDED(hr)) 
  119.         {
  120.             // Set the rendering mode and number of streams.  
  121.             IVMRFilterConfig* pConfig;
  122.             hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
  123.             if( SUCCEEDED(hr)) 
  124.             {
  125.                 pConfig->SetRenderingMode(VMRMode_Windowless);
  126.                 pConfig->Release();
  127.             }
  128.             hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&m_pWC);
  129.             if( SUCCEEDED(hr)) 
  130.             {
  131.                 m_pWC->SetVideoClippingWindow(hWnd);
  132.                 
  133.             }
  134.         }
  135.         pVmr->Release();
  136.     }
  137.     return hr;
  138. }
  139. bool CVMR_Capture::BindFilter(int deviceId, IBaseFilter **pFilter)
  140. {
  141. if (deviceId < 0)
  142. return false;
  143.     // enumerate all video capture devices
  144. CComPtr<ICreateDevEnum> pCreateDevEnum;
  145.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
  146.   IID_ICreateDevEnum, (void**)&pCreateDevEnum);
  147.     if (hr != NOERROR)
  148. {
  149. return false;
  150. }
  151.     CComPtr<IEnumMoniker> pEm;
  152.     hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
  153. &pEm, 0);
  154.     if (hr != NOERROR) 
  155. {
  156. return false;
  157.     }
  158.     pEm->Reset();
  159.     ULONG cFetched;
  160.     IMoniker *pM;
  161. int index = 0;
  162.     while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId)
  163.     {
  164. IPropertyBag *pBag;
  165. hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
  166. if(SUCCEEDED(hr)) 
  167. {
  168. VARIANT var;
  169. var.vt = VT_BSTR;
  170. hr = pBag->Read(L"FriendlyName", &var, NULL);
  171. if (hr == NOERROR) 
  172. {
  173. if (index == deviceId)
  174. {
  175. pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
  176. }
  177. SysFreeString(var.bstrVal);
  178. }
  179. pBag->Release();
  180. }
  181. pM->Release();
  182. index++;
  183.     }
  184. return true;
  185. }
  186. HRESULT CVMR_Capture::InitVideoWindow(HWND hWnd,int width, int height)
  187. {
  188. // Set the grabbing size
  189.     // First we iterate through the available media types and 
  190.     // store the first one that fits the requested size.
  191.     // If we have found one, we set it.
  192.     // In any case we query the size of the current media type
  193.     // to have this information for clients of this class.
  194.     //     Gerhard Reitmayr <reitmayr@i ...............>
  195. HRESULT hr;
  196. RECT rcDest;
  197.     CComPtr<IAMStreamConfig> pConfig;
  198.     IEnumMediaTypes *pMedia;
  199.     AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL;
  200.     hr = m_pCamOutPin->EnumMediaTypes( &pMedia );
  201.     if(SUCCEEDED(hr))
  202.     {
  203.         while(pMedia->Next(1, &pmt, 0) == S_OK)
  204.         {
  205.             if( pmt->formattype == FORMAT_VideoInfo )
  206.             {
  207.                 VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat;
  208.                 // printf("Size %i  %in", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight );
  209.                 if( vih->bmiHeader.biWidth == width && vih->bmiHeader.biHeight == height )
  210.                 {
  211.                     pfnt = pmt;
  212.                     // printf("found mediatype with %i %in", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight );
  213. //char test[100];
  214. //sprintf(test,"Width=%dnHeight=%d",vih->bmiHeader.biWidth, vih->bmiHeader.biHeight);
  215. //MessageBox(test);
  216.                     break;
  217.                 }
  218.                 DeleteMediaType( pmt );
  219.             }                        
  220.         }
  221.         pMedia->Release();
  222.     }
  223.     hr = m_pCamOutPin->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig );
  224.     if(SUCCEEDED(hr))
  225.     {
  226.         if( pfnt != NULL )
  227.         {
  228.             hr=pConfig->SetFormat( pfnt );
  229. //if(SUCCEEDED(hr))        
  230. //MessageBox("OK");
  231.             DeleteMediaType( pfnt );
  232.         }
  233.         hr = pConfig->GetFormat( &pfnt );
  234.         if(SUCCEEDED(hr))
  235.         {
  236.             m_nWidth = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biWidth;
  237.             m_nHeight = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biHeight;
  238.             DeleteMediaType( pfnt );
  239.         }
  240.     }
  241. ::GetClientRect (hWnd,&rcDest);
  242.     hr = m_pWC->SetVideoPosition(NULL, &rcDest);
  243.     return hr;
  244. }
  245. void CVMR_Capture::StopCapture()
  246. {
  247.     HRESULT hr;
  248. if((m_psCurrent == Paused) || (m_psCurrent == Running))
  249.     {
  250.         LONGLONG pos = 0;
  251.         hr = m_pMC->Stop();
  252.         m_psCurrent = Stopped;
  253.         // Display the first frame to indicate the reset condition
  254.         hr = m_pMC->Pause();
  255.     }
  256. // CWnd::FromHandle(m_hParentWnd)->ReleaseDC(m_pDC);
  257. m_Bitmap.DeleteObject();
  258. if (m_MemDC.GetSafeHdc()!=NULL)
  259. {
  260. m_MemDC.DeleteDC();
  261. }
  262.    
  263. }
  264. void CVMR_Capture::CloseInterfaces(void)
  265. {
  266.     HRESULT hr;
  267.     
  268. // Stop media playback
  269.     if(m_pMC)
  270.         hr = m_pMC->Stop();     
  271.     m_psCurrent = Stopped;  
  272. // Disable event callbacks
  273. /*
  274.     if (pME)
  275.         hr = m_pME->SetNotifyWindow((OAHWND)NULL, 0, 0);
  276. */
  277. // SAFE_RELEASE(pME);
  278.     // Release and zero DirectShow interfaces
  279. if(m_pCamOutPin)
  280. m_pCamOutPin->Disconnect ();
  281. SAFE_RELEASE(m_pCamOutPin);        
  282.     SAFE_RELEASE(m_pMC);    
  283.     SAFE_RELEASE(m_pGB);    
  284.     SAFE_RELEASE(m_pWC);
  285. SAFE_RELEASE(m_pDF);
  286. //delete allocated memory 
  287. if(m_pFrame!=NULL)
  288. delete []m_pFrame;
  289. }
  290. //Capture RAW IMAGE BITS 24bits/pixel
  291. DWORD CVMR_Capture::ImageCapture(LPCTSTR szFile)
  292. {
  293. BYTE *pImage;
  294. DWORD dwSize,dwWritten;
  295. dwSize=this->GrabFrame ();
  296. this->GetFrame (&pImage);
  297. HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
  298.   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  299. if (hFile == INVALID_HANDLE_VALUE)
  300. return FALSE;
  301. WriteFile(hFile, (LPCVOID)pImage , m_nFramelen, &dwWritten, 0);
  302. // Close the file
  303. CloseHandle(hFile);
  304. return dwWritten;
  305. }
  306. void CVMR_Capture::DeleteMediaType(AM_MEDIA_TYPE *pmt)
  307. {
  308.     // allow NULL pointers for coding simplicity
  309.     if (pmt == NULL) {
  310.         return;
  311.     }
  312.     if (pmt->cbFormat != 0) {
  313.         CoTaskMemFree((PVOID)pmt->pbFormat);
  314.         // Strictly unnecessary but tidier
  315.         pmt->cbFormat = 0;
  316.         pmt->pbFormat = NULL;
  317.     }
  318.     if (pmt->pUnk != NULL) {
  319.         pmt->pUnk->Release();
  320.         pmt->pUnk = NULL;
  321.     }
  322.     CoTaskMemFree((PVOID)pmt);
  323. }
  324. DWORD CVMR_Capture::GrabFrame()
  325. {
  326. long lOut=-1;
  327. if(m_pWC ) 
  328.     {
  329.        BYTE* lpCurrImage = NULL;
  330.         // Read the current video frame into a byte buffer.  The information
  331.         // will be returned in a packed Windows DIB and will be allocated
  332.         // by the VMR.
  333.         if(m_pWC->GetCurrentImage(&lpCurrImage) == S_OK)
  334.         {
  335. LPBITMAPINFOHEADER  pdib = (LPBITMAPINFOHEADER) lpCurrImage;
  336. if(m_pFrame==NULL || (pdib->biHeight * pdib->biWidth * 3) !=m_nFramelen )
  337. {
  338. if(m_pFrame!=NULL)
  339. delete []m_pFrame;
  340. m_nFramelen=pdib->biHeight * pdib->biWidth * 3;
  341. m_pFrame=new BYTE [pdib->biHeight * pdib->biWidth * 3] ;
  342. }
  343. if(pdib->biBitCount ==32) 
  344. {
  345. DWORD  dwSize=0, dwWritten=0;
  346. BYTE *pTemp32;
  347. pTemp32=lpCurrImage + sizeof(BITMAPINFOHEADER);
  348. //change from 32 to 24 bit /pixel
  349. this->Convert24Image(pTemp32, m_pFrame, pdib->biSizeImage);
  350. }
  351. CoTaskMemFree(lpCurrImage); //free the image 
  352. }
  353. else
  354. {
  355. return lOut;
  356. }
  357. }
  358. else
  359. {
  360. return lOut;
  361. }
  362.     return lOut=m_nFramelen;
  363. }
  364. bool CVMR_Capture::Convert24Image(BYTE *p32Img, BYTE *p24Img,DWORD dwSize32)
  365. {
  366. if(p32Img != NULL && p24Img != NULL && dwSize32>0)
  367. {
  368. DWORD dwSize24;
  369. dwSize24=(dwSize32 * 3)/4;
  370. BYTE *pTemp,*ptr;
  371. //pTemp=p32Img + sizeof(BITMAPINFOHEADER); ;
  372. pTemp=p32Img;
  373. ptr=p24Img + dwSize24-1 ;
  374. int ival=0;
  375. for (DWORD index = 0; index < dwSize32/4 ; index++)
  376. {
  377. unsigned char r = *(pTemp++);
  378. unsigned char g = *(pTemp++);
  379. unsigned char b = *(pTemp++);
  380. (pTemp++);//skip alpha
  381. *(ptr--) = b;
  382. *(ptr--) = g;
  383. *(ptr--) = r;
  384. }
  385. }
  386. else
  387. {
  388. return false;
  389. }
  390. return true;
  391. }
  392. BOOL CVMR_Capture::Pause()
  393. {
  394.     if (!m_pMC)
  395.         return FALSE;
  396.   
  397.     if(((m_psCurrent == Paused) || (m_psCurrent == Stopped)) )
  398.     {
  399. this->StopCapture();
  400.         if (SUCCEEDED(m_pMC->Run()))
  401.             m_psCurrent = Running;
  402.     }
  403.     else
  404.     {
  405.         if (SUCCEEDED(m_pMC->Pause()))
  406.             m_psCurrent = Paused;
  407.     }
  408. return TRUE;
  409. }
  410. DWORD CVMR_Capture::GetFrame(BYTE **pFrame)
  411. {
  412. if(m_pFrame && m_nFramelen)
  413. {
  414. *pFrame=m_pFrame;
  415. }
  416. return m_nFramelen;
  417. }
  418. int  CVMR_Capture::EnumDevices(HWND hList)
  419. {
  420. if (!hList)
  421. return  -1;
  422. int id = 0;
  423.     // enumerate all video capture devices
  424. CComPtr<ICreateDevEnum> pCreateDevEnum;
  425. //    ICreateDevEnum *pCreateDevEnum;
  426.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
  427.   IID_ICreateDevEnum, (void**)&pCreateDevEnum);
  428.     if (hr != NOERROR)
  429. {
  430. return -1;
  431. }
  432.     CComPtr<IEnumMoniker> pEm;
  433.     hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
  434. &pEm, 0);
  435.     if (hr != NOERROR) 
  436. {
  437. return -1 ;
  438.     }
  439.     pEm->Reset();
  440.     ULONG cFetched;
  441.     IMoniker *pM;
  442.     while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
  443.     {
  444. IPropertyBag *pBag;
  445. hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
  446. if(SUCCEEDED(hr)) 
  447. {
  448. VARIANT var;
  449. var.vt = VT_BSTR;
  450. hr = pBag->Read(L"FriendlyName", &var, NULL);
  451. if (hr == NOERROR) 
  452. {
  453. TCHAR str[2048];
  454. id++;
  455. WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
  456. (long)SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
  457. SysFreeString(var.bstrVal);
  458. }
  459. pBag->Release();
  460. }
  461. pM->Release();
  462.     }
  463. return id;
  464. }
  465. typedef struct{ 
  466. int lui;
  467. int luj;
  468. int h;
  469. int w;
  470.  }AREA; 
  471. typedef struct{ 
  472. int upx;
  473. int upy;
  474. int width;
  475. int height;
  476.     AREA leftEyeArea;
  477.     AREA rightEyeArea;
  478.     AREA leftPupil;
  479. AREA rightPupil;
  480.     AREA noseArea;
  481. AREA mouthArea;
  482.  }FACE_LOCATION; 
  483. /*
  484. BOOL UsedFuction(unsigned char * pImage, int Width, int Height, 
  485. FACE_LOCATION * face, int * FaceNumber);
  486. HINSTANCE Dll_handler;
  487. typedef BOOL(DLLTEST)(BYTE* pData,  int w, int h, int* FaceLeftUpX, int* 
  488. FaceLeftUpY,
  489. int* FaceRightDownX, int* FaceRightDownY, int* FaceNumber);
  490. DLLTEST* DllTest;
  491. Dll_handler = 
  492. LoadLibrary("F:\最新文档2006年12月\newdll\Release\newdll");
  493. DllTest=(DLLTEST*)GetProcAddress(Dll_handler,"fuction_1");
  494. iReturn1=(*DllTest)(pData, w, h, FaceLeftUpX,FaceLeftUpY, 
  495. FaceRightDownX,FaceRightDownY, &FaceNumber);
  496. if (!nRet){   TRACE("Failed to detect face.rn");
  497. delete pImg;
  498. continue;
  499. }
  500. FreeLibrary(Dll_handler);
  501. Dll_handler=NULL;
  502. */
  503. BOOL CVMR_Capture::Trace(BYTE *pImageByte)
  504. {
  505. ////////////////////////////////////////////////////////////////////////
  506. // MoveWindow(100,100,320,240);
  507. /////////////////////////////////////
  508. if (lpVideo == NULL) 
  509. return (LRESULT) TRUE;
  510. //////////////////////////////////
  511.     unsigned char* pImgData;
  512. pImgData=pImageByte;
  513. int x, y, nX, nY;
  514. nX = 1;
  515. nY = 1;
  516. const int nMosaicWidth=4;
  517. const int nMosaicHeight=4;
  518. CBitmap *pOldBitmap;
  519. pOldBitmap=lpVideo->m_MemDC.SelectObject(&lpVideo->m_Bitmap);
  520. lpVideo->m_MoveTrace.GetDIBBit(pImgData);//lpVHdr->lpData
  521. lpVideo->m_MoveTrace.Extract(nX, nY);
  522. lpVideo->m_MoveTrace.Grey(); //m_Grey1
  523. lpVideo->m_MoveTrace.Sobel(); //m_Grey1
  524. int nThreshold=lpVideo->m_MoveTrace.GetThreshold(30);// ThresholdDIB((LPSTR)lpVideo->m_MoveTrace.m_pGrey1,320,240);
  525. lpVideo->m_MoveTrace.FrameMinus(); //m_pGrey[x]=abs(m_pGrey1[x] - m_pGrey2[x]);
  526. lpVideo->m_MoveTrace.Mosaic(nMosaicWidth, nMosaicHeight); //m_pGrey --> m_pMosaic
  527. lpVideo->m_MoveTrace.Dither(nThreshold); //m_pMosaic  
  528. for( y=0;y<lpVideo->m_iHeight;y+=1)
  529. {
  530. for( x=0;x<lpVideo->m_iWidth;x+=1)
  531. {
  532. int nPos = y/nY*lpVideo->m_iWidth/nX+x/nX;
  533. int nTemp = lpVideo->m_MoveTrace.m_pMosaic[nPos];
  534. // int nTemp = lpVideo->m_MoveTrace.m_pGrey[nPos];
  535. // int nTemp = lpVideo->m_MoveTrace.m_pGrey1[nPos];
  536. lpVideo->m_MemDC.SetPixel(x,lpVideo->m_iHeight-1-y,RGB(nTemp,nTemp,nTemp));
  537. }
  538. }
  539. lpVideo->m_MoveTrace.SaveFrame(); //m_pGrey2[x] = m_pGrey1[x];
  540. CRect rect;
  541. bool bRet1=lpVideo->m_MoveTrace.Rectangle(rect,100,5);//m_pMosaic
  542. if (bRet1)
  543. {
  544. lpVideo->m_MemDC.Draw3dRect(&rect, RGB(0, 255, 0), RGB(0, 255, 0));
  545. lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_NextRect, RGB(0, 0, 255), RGB(0, 0, 255));
  546. lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_CurrentRect, RGB(255, 0, 0), RGB(255, 0, 0));
  547. }
  548. //SetDIBitsToDevice(lpVideo->m_pDC->m_hDC,0,0,m_iWidth,m_iHeight,0,0,);
  549. BOOL bRet=lpVideo->m_pDC->BitBlt(
  550. 250,0,
  551. lpVideo->m_iWidth,
  552. lpVideo->m_iHeight,
  553. &lpVideo->m_MemDC,
  554. 0,0,
  555. SRCCOPY);
  556. lpVideo->m_MemDC.SelectObject(pOldBitmap);
  557. //保存图片
  558. CTime Time=CTime::GetCurrentTime();
  559. CString strTime = Time.Format("%H%M%S");
  560. iMinNew=Time.GetMinute( );
  561. strTime="pics\"+strTime;
  562. if((iMinNew-iMinOld)>1)m_bStorageData=TRUE;
  563. if(lpVideo->m_bStorageData)
  564. {
  565. // lpVideo->SaveImage(lpVHdr);
  566. lpVideo->WriteAsBMP(strTime.GetBuffer(strTime.GetLength()),pImgData,320,240);
  567. lpVideo->m_bStorageData = FALSE;
  568. iMinOld=iMinNew;
  569. }
  570. return true;
  571. ////////////////////////////////////////////////////////////////////////
  572.    
  573. }
  574. void CVMR_Capture::MoveWindow(int x,int y,int nWidth,int nHeight)
  575. {
  576. //m_iWidth = nWidth;
  577. //m_iHeight = nHeight;
  578. ::MoveWindow(m_hCapWnd,x,y,nWidth,nHeight,TRUE); 
  579. }
  580. /////////////////////////////////////////////////////////////////////////////////
  581. BOOL CVMR_Capture::WriteAsBMP(char* szFileName,unsigned char* pImgData,int nWidth,int nHeight)
  582. {
  583. char aFileName[255];
  584. int nStrLen;
  585. if(strstr(szFileName,".")==NULL)
  586. {
  587. strcpy(aFileName,szFileName);
  588. strcat(aFileName,".bmp");
  589. }
  590. else
  591. {
  592. nStrLen=strlen(szFileName)-strlen(strstr(szFileName,"."));
  593. strncpy(aFileName,szFileName,nStrLen);
  594. aFileName[nStrLen]='';
  595. strcat(aFileName,".bmp");
  596. }
  597. BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
  598. /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
  599. bmfHdr.bfType = 0x4d42;  // "BM"
  600. // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
  601. int nImgWidth;
  602. if (nWidth%4==0)
  603. {
  604. nImgWidth=nWidth*3;
  605. }
  606. else
  607. {
  608. nImgWidth=nWidth*3+nWidth%4;
  609. }
  610. bmfHdr.bfSize =(DWORD)( nImgWidth*nHeight + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) );
  611. bmfHdr.bfReserved1 = 0;
  612. bmfHdr.bfReserved2 = 0;
  613. bmfHdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
  614. BITMAPINFOHEADER BMIH;   // Pointer to DIB info structure
  615. BMIH.biSize=sizeof(BITMAPINFOHEADER);
  616. BMIH.biHeight=nHeight;
  617. BMIH.biWidth=nWidth;
  618. BMIH.biPlanes=1;
  619. BMIH.biBitCount=24;
  620. BMIH.biCompression=BI_RGB;
  621. BMIH.biSizeImage=nImgWidth*nHeight;
  622. BMIH.biXPelsPerMeter=0xec4;
  623. BMIH.biYPelsPerMeter =0xec4;
  624. BMIH.biClrUsed =0;
  625. BMIH.biClrImportant=0;
  626. FILE *pFile;
  627. pFile=fopen(aFileName,"wb");
  628. if (pFile==NULL)
  629. {
  630. return FALSE;
  631. }
  632. BYTE aTemp[12]={0};
  633. try {
  634. // Write the file header
  635. fwrite((BYTE*)&bmfHdr,1,sizeof(BITMAPFILEHEADER),pFile);
  636. // Write the DIB header
  637.         fwrite((BYTE*)&BMIH,1,sizeof(BITMAPINFOHEADER),pFile);
  638. // Write the DIB bits
  639. int j;
  640. for (j=0;j<nHeight;j++)
  641. {
  642. int i;
  643. i=nHeight-j;
  644. fwrite(pImgData+i*nWidth*3,1,nWidth*3,pFile);
  645. fwrite(aTemp,1,nWidth%4,pFile);
  646. }
  647.     }
  648.     catch(...)
  649. {
  650. fclose(pFile);
  651.         return FALSE;
  652.     }
  653. fclose(pFile);
  654.     return TRUE;
  655. }