DirectShow 抓圖 |
尚未結案
|
炎峰
一般會員 發表:7 回覆:9 積分:3 註冊:2011-03-16 發送簡訊給我 |
各位大大好
小弟專題會使用到影像處理 我們已在 VFW 下做出了主要功能,但是因為速度太慢,想換成 DirectShow 試試看 軟體是 C Builder XE,因為小弟功力不足無法成功 compiler DSPack,因此是直接使用 CB XE 內建的 DirectShow (可直接 #include 使用 cppfans 逍遙遊 大大的 PlayCap2010 為範例下修改 目前已能在 Panel 上顯示畫面,因為要做處理,我們想要把圖片/Buffer給抓下來 但是畫面只會一直撥放,並無法把圖片存下來 (小弟這邊先求能把單張圖片抓下來,後續再去處理連續抓圖、不同時間之圖)... 精簡程式碼如下: [code cpp] HRESULT TForm1::SampleGrabber(void) { HRESULT hr; IBaseFilter *pSG_Filter = NULL; pGrabber = NULL; long cbBuffer = 0; BYTE *pBuffer = new BYTE[cbBuffer]; hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pSG_Filter); if (FAILED(hr)) { Msg(TEXT("Creat Sample Graber com faild! hr=0x%x"), hr); return hr; } hr = g_pGraph->AddFilter(pSG_Filter, L"SampleGrab"); // 將 Sample Grabber 加入 filter graph 中 if (FAILED(hr)) { Msg(TEXT("Add Filter - DampleGrabber Error! hr=0x%x"), hr); return hr; } IBaseFilter *pNull = NULL; hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pNull); if (FAILED(hr)) { Msg(TEXT("Creat NullRenderer com faild! hr=0x%x"), hr); return hr; } hr = g_pGraph->AddFilter(pNull, L"NullRender"); if (FAILED(hr)) { Msg(TEXT("Add Filter - NullRenderer Error! hr=0x%x"), hr); return hr; } AM_MEDIA_TYPE mt; HDC hdc = GetDC(NULL); int iBitDepth = GetDeviceCaps(hdc, BITSPIXEL); ReleaseDC(NULL, hdc); memset(&mt, 0, sizeof(AM_MEDIA_TYPE)); mt.majortype = MEDIATYPE_Video; switch (iBitDepth) { case 8: mt.subtype = MEDIASUBTYPE_RGB8; break; case 16: mt.subtype = MEDIASUBTYPE_RGB555; break; case 24: mt.subtype = MEDIASUBTYPE_RGB24; break; case 32: mt.subtype = MEDIASUBTYPE_RGB32; break; default: return E_FAIL; } hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber); if (FAILED(hr)) { Msg(TEXT("Error @ pSG_Filter->QueryInterface ")); return hr; } hr = pGrabber->SetMediaType(&mt); if (FAILED(hr)) { Msg(TEXT("Error @ pGrabber->SetMediaType ")); return hr; } hr = pGrabber->SetOneShot(false); if (FAILED(hr)) { Msg(TEXT("Error @ pGrabber->SetOneShot(FALSE) ")); return hr; } hr = pGrabber->SetBufferSamples(true); if (FAILED(hr)) { Msg(TEXT("Error @ pGrabber->SetBufferSamples(TRUE) ")); return hr; } /* 此處為使用 ISampleGrabberCB::BufferCB 已繼承寫好類似這邊的部分,測試過仍是一樣的問題 因此這邊希望能先抓出單張圖 CSampleGrabberCB g_StillCapCB; pGrabber->SetCallback(&g_StillCapCB, 1); // 0 → SampleCB , 傳進來的位址是 Sample 原始資料 // 1 → BufferCB , 傳進來的位址是 Buffer 的資料 */ hr = g_pMC->Run(); if (FAILED(hr)) { Msg(TEXT("Couldn't run the graph! hr=0x%x"), hr); return hr; } /* 這邊若是使用 Sleep (200~2000 都測過) 則後續 pGrabber->GetCurrentBuffer(&cbBuffer, NULL) 會出現錯誤 hr = 0x80040227 (VFW_E_WRONG_STATE) 若使用 Media Event 的 WaitForCompletion 則是會一直卡在這邊,不會往下執行了 */ //Sleep(200); long EvCode = 0; hr = g_pME->WaitForCompletion( INFINITE, &EvCode ); if (FAILED(hr)) { Msg(TEXT("Couldn't Wait For Completion")); return hr; } hr = pGrabber->GetCurrentBuffer(&cbBuffer, NULL); if (FAILED(hr)) { Msg(TEXT("Couldn't Get Current Buffer (NULL)! hr=0x%x"), hr); return hr; } if (!pBuffer) ShowMessage("pBuffer out of Memory"); hr = pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer); if (FAILED(hr)) { Msg(TEXT("Couldn't Get Current Buffer! hr=0x%x"), hr); return hr; } hr = pGrabber->GetConnectedMediaType(&mt); if (FAILED(hr)) { Msg(TEXT("Couldn't get Connected Media Type ")); return hr; } VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)mt.pbFormat; if ((mt.formattype == FORMAT_VideoInfo) && (mt.cbFormat >= sizeof(VIDEOINFOHEADER)) && (mt.pbFormat != NULL) ) pVih = (VIDEOINFOHEADER*)mt.pbFormat; else { FreeMediaType(mt); Msg(TEXT("Couldn't get Video Info Header!")); return VFW_E_INVALIDMEDIATYPE; } HANDLE hf = CreateFile(L"tmp.bmp", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, NULL, NULL ); if( hf == INVALID_HANDLE_VALUE ) return E_FAIL; BITMAPFILEHEADER bfh; memset( &bfh, 0, sizeof( bfh ) ); bfh.bfType = 0x4D42; bfh.bfSize = sizeof( bfh ) cbBuffer sizeof( BITMAPINFOHEADER ); bfh.bfOffBits = sizeof(BITMAPINFOHEADER) sizeof( BITMAPFILEHEADER ); DWORD Written = 0; WriteFile( hf, &bfh, sizeof( bfh ), &Written, NULL ); BITMAPINFO bi; BITMAPINFOHEADER bih; memset( &bih, 0, sizeof( bih ) ); bih.biSize = sizeof( bih ); bih.biWidth = pVih->bmiHeader.biWidth; bih.biHeight = pVih->bmiHeader.biHeight; bih.biPlanes = pVih->bmiHeader.biPlanes; bih.biBitCount = pVih->bmiHeader.biBitCount; Written = 0; WriteFile( hf, &bih, sizeof( bih ), &Written, NULL ); Written = 0; WriteFile(hf, pBuffer, sizeof( pBuffer ), &Written, NULL); CloseHandle(hf); FreeMediaType(mt); SafeRelease(pSG_Filter); SafeRelease(pGrabber); delete stream; delete tmp; return S_OK; } [/code] 問題就如上面說的,希望有大大可以指點迷津 如是小弟爬文不足或是犯了白痴的錯誤,請大大用力鞭吧 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |