2011-08-09 30 views
3

ビデオフレーム(ウェブカメラ)に直接描画するにはどうすればよいですか?コーナーにウォーターマークを配置する必要があるので、ファイルにビデオをキャプチャすると、このウォーターマークは各フレームにあるはずです。次のようにC++ DirectShow W32直接フレームに描画

私のセットアップは次のとおりです。

struct Sampler : public CBaseVideoRenderer 
{ 
    Sampler(IUnknown* unk, HRESULT *hr) : CBaseVideoRenderer(__uuidof(CLSID_Sampler), NAME("Frame Sampler"), unk, hr) {}; 

    HRESULT CheckMediaType(const CMediaType *media) 
    {  
     VIDEOINFO* vi; 
     if(!IsEqualGUID(*media->Subtype(), MEDIASUBTYPE_RGB24) || !(vi=(VIDEOINFO *)media->Format())) return E_FAIL; 
     bmih=vi->bmiHeader; 
     return S_OK; 
    } 
    HRESULT DoRenderSample(IMediaSample *sample) 
    { 
      int w=bmih.biWidth; 
      int h=bmih.biHeight; 
      BYTE* data; sample->GetPointer(&data); 
      HDC dc=GetDC(hCameraWindow); 
      BITMAPINFO bmi={0}; bmi.bmiHeader=bmih; RECT r; GetClientRect(hCameraWindow, &r); 
      StretchDIBits(dc,0,0,r.right,r.bottom,0,0,bmih.biWidth,bmih.biHeight,data,&bmi,DIB_RGB_COLORS,SRCCOPY); 
      ReleaseDC(hCameraWindow,dc); 
      return S_OK; 
    } 
    HRESULT ShouldDrawSampleNow(IMediaSample *sample, REFERENCE_TIME *start, REFERENCE_TIME *stop) 
    { 
     return S_OK; // disable droping of frames 
    } 
}; 

と初期化:

hCameraWindow= CreateWindowEx(WS_EX_CLIENTEDGE, "Static", NULL, WS_CHILD | WS_VISIBLE , 20, 5, 640, 480, okno, NULL, GetModuleHandle(NULL), NULL); 
ShowWindow(hCameraWindow,SW_SHOW); 
if(!hCameraWindow)exit(0); 


IGraphBuilder* graph= 0;  hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC,IID_IGraphBuilder, (void **)&graph); 
IMediaControl* ctrl = 0;  hr = graph->QueryInterface(IID_IMediaControl, (void **)&ctrl); 
    IMediaEventEx* mediaEvent=0; hr = graph->QueryInterface(IID_IMediaEvent, (LPVOID *) &mediaEvent); 
    IVideoWindow* m_pVWMoniker=0; hr = graph->QueryInterface(IID_IVideoWindow, (LPVOID *) &m_pVWMoniker); 

m_pVWMoniker->put_Owner((OAHWND)hCameraWindow); 
m_pVWMoniker->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN); 
m_pVWMoniker->put_Visible(OATRUE); 
m_pVWMoniker->put_MessageDrain((OAHWND)hCameraWindow); 

Sampler*  sampler  = new Sampler(0,&hr); 


IPin*   rnd = 0; hr = sampler->FindPin(L"In", &rnd); 
          hr = graph->AddFilter((IBaseFilter*)sampler, L"Sampler"); 

ICreateDevEnum* devs = 0; hr = CoCreateInstance (CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) &devs); 
IEnumMoniker* cams = 0; hr = devs?devs->CreateClassEnumerator (CLSID_VideoInputDeviceCategory, &cams, 0):0; 
IMoniker*  mon = 0; hr = cams?cams->Next (1, &mon, 0):0; 
IBaseFilter* cam = 0; hr = mon?mon->BindToObject(0,0,IID_IBaseFilter, (void**)&cam):0; 
IEnumPins*  pins = 0; hr = cam?cam->EnumPins(&pins):0; 
IPin*   cap = 0; hr = pins?pins->Next(1,&cap, 0):0; 
          hr = graph->AddFilter(cam, L"Capture Source"); 
    // Change resolution 
    IAMStreamConfig *pConfig=0; 
    if(cap->QueryInterface(IID_IAMStreamConfig, (void **)&pConfig) == S_OK) 
    { 
     int iCount = 0; 
     int iSize = 0;  
     hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize); 
     VIDEO_STREAM_CONFIG_CAPS caps; 
     AM_MEDIA_TYPE *pmtConfig; 
     for(int i=0;i<iSize;i++) 
     {   
      pConfig->GetStreamCaps(i, &pmtConfig, (BYTE*)&caps); 
      // if a resoltion has been found, set format to it 
      if(caps.MaxOutputSize.cx == 640 && caps.MinOutputSize.cy == 480) 
      { 
       pConfig->SetFormat(pmtConfig); 
      } 

     } 
     DeleteMediaType(pmtConfig); 
    } 

hr = graph->Connect(cap,rnd); 
hr = graph->Render(cap); 
hr = ctrl->Run(); 

私は "DoRenderSample" でフレームにアクセスすることができます。 DShowはDShowの初心者の方にとってはとてもフレンドリーではありません。

私はVFWから切り替えたので、フレームにGDI +で描画する必要があります。SetBitmapBits/GetBitmapBitsで可能ですか?

答えて

1

は、誰もが興味を持っている場合、私はそれは、作業持って[OK]を を解決しました - 私は自分自身でそれを残して、いないエラー処理 - コードに以下の見て、それはのGdiPlusでテキストを描画します。

int m_stride; 
VIDEOINFOHEADER m_videoInfo; 


    HRESULT CheckMediaType(const CMediaType *media) 
    {  
     VIDEOINFO* vi; 
     if(!IsEqualGUID(*media->Subtype(), MEDIASUBTYPE_RGB24) || !(vi=(VIDEOINFO *)media->Format())) return E_FAIL; 
     bmih=vi->bmiHeader; 
     m_stride = bmih.biBitCount/8 * bmih.biWidth;  
     return S_OK; 
    } 

HRESULT DoRenderSample(IMediaSample *sample) 
    {  BYTE* data; 
      int w=bmih.biWidth; 
      int h=bmih.biHeight; 
      int len = sample->GetActualDataLength(); 
      sample->GetPointer(&data); 


      BITMAPINFOHEADER bih = bmih; 
      Bitmap bmp(bih.biWidth, bih.biHeight, (bmih.biBitCount/8*bmih.biWidth), PixelFormat24bppRGB, data); 
      Graphics graphics(&bmp); 
      WCHAR wavists[1024];  
      char txt[1024]; 
      sprintf(txt,"THIS TEXT IS DISPLAYED ON EACH FRAME");MultiByteToWideChar(GetACP(), 0, txt, -1, wavists, strlen(txt));  
      graphics.DrawString(wavists,strlen(txt),&Font(&FontFamily(L"Tahoma"), 16, FontStyleBold, UnitPixel),PointF(0,0),&SolidBrush(Color(200,0,255,0))); 





      HDC dc=GetDC(hCameraWindow); 
      BITMAPINFO bmi={0}; bmi.bmiHeader=bmih; RECT r; GetClientRect(hCameraWindow, &r); 
      StretchDIBits(dc,0,0,r.right,r.bottom,0,0,bmih.biWidth,bmih.biHeight,data,&bmi,DIB_RGB_COLORS,SRCCOPY); 
      ReleaseDC(hCameraWindow,dc); 



} 
関連する問題