试图制作VMR-9 MixerBitmap& GDI的工作

时间:2010-06-10 14:24:47

标签: c++ directshow gdi

我正在尝试在某些视频上叠加位图。我在内存中创建一个位图,然后我调用SelectObject将其选择到memoryDC中,这样我就可以对它执行DrawText操作。

我根本没有在屏幕上看到任何结果 - 有人能说明为什么吗?

感谢

 HRESULT MyGraph::MixTextOverVMR9(LPCTSTR szText)
{
 // create a bitmap object using GDI, render the text to it accordingly
 // then Sets the bitmap as an alpha bitmap to the VMR9, so that it can be overlayed. 

 HRESULT    hr    = S_OK;
 CBitmap    bmpMem; 
 CFont    font;
 LOGFONT    logicfont;

 CRect    rcText;
 CRect    rcVideo;
 VMR9AlphaBitmap  alphaBmp;

 HWND    hWnd   = this->GetFirstRendererWindow();
 COLORREF   clrText   = RGB(255, 255, 0);
 COLORREF   clrBlack  = RGB(0,0,0);
 HDC     hdcHwnd   = NULL; 
 CDC     dcMem;

 LONG    lWidth;
 LONG    lHeight; 


 if( ! m_spVideoRenderer.p )
  return E_NOINTERFACE;

 if( !m_spWindowlessCtrl.p )
  return E_NOINTERFACE;

 if( ! m_spIMixerBmp9.p )
 {  
  m_spIMixerBmp9 = m_spVideoRenderer;

  if( ! m_spIMixerBmp9.p )
   return E_NOINTERFACE;
 }

 // create the font..
 LPCTSTR sFont = _T("Times New Roman");
 memset(&logicfont, 0, sizeof(LOGFONT));
 logicfont.lfHeight   = 42;
 logicfont.lfWidth   = 20;
 logicfont.lfStrikeOut  = 0;
    logicfont.lfUnderline  = 0;
 logicfont.lfItalic   = FALSE;     
 logicfont.lfWeight   = FW_NORMAL;
    logicfont.lfEscapement  = 0; 
 logicfont.lfCharSet   = ANSI_CHARSET;
 logicfont.lfQuality   = ANTIALIASED_QUALITY;
 logicfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;

 wcscpy_s( &logicfont.lfFaceName[0], wcslen(sFont)*2, sFont );
 font.CreateFontIndirectW(&logicfont);

 // create a compatible memDC from the video window's HDC
 if( hWnd == NULL )
  return E_FAIL;

 hdcHwnd = GetDC(hWnd);
 dcMem = CreateCompatibleDC(hdcHwnd);

 // get the required bitmap metrics from the MediaBuffer 
 if( ! SUCCEEDED(m_spWindowlessCtrl->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL)) )
  return E_FAIL;

 // create a bitmap for the text
 bmpMem.CreateCompatibleBitmap(dcMem.m_hDC, lWidth, lHeight);

 SelectBitmap (dcMem.m_hDC, bmpMem); 
 SetBkMode  (dcMem.m_hDC, TRANSPARENT);
 SetTextColor (dcMem.m_hDC, clrText);
 SelectFont  (dcMem.m_hDC, font.m_hFont);

 // draw the text
 DrawTextW(dcMem.m_hDC, szText, wcslen(szText), rcText, DT_CALCRECT | DT_NOPREFIX );
 DrawTextW(dcMem.m_hDC, szText, wcslen(szText), rcText, DT_NOPREFIX );

 // Set the alpha bitmap on the VMR9 renderer 
 memset(&alphaBmp, 0, sizeof(VMR9AlphaBitmap)); 

 alphaBmp.rDest.left  = 0;
 alphaBmp.rDest.top  = 0.5;
 alphaBmp.rDest.right = 0.5;
 alphaBmp.rDest.bottom = 1;


 alphaBmp.dwFlags  = VMR9AlphaBitmap_hDC;
 alphaBmp.hdc   = dcMem.m_hDC;
 alphaBmp.pDDS   = NULL;
 alphaBmp.rSrc   = rcText;    // rect to copy from the source image 
 alphaBmp.fAlpha   = 0.5f;     // transparency value (1.0 is opaque, 0.0 is transparent)
 alphaBmp.clrSrcKey  = clrText;
 // alphaBmp.dwFilterMode = MixerPref9_AnisotropicFiltering;


 hr = m_spIMixerBmp9->SetAlphaBitmap(&alphaBmp);

 DeleteDC(hdcHwnd);
 dcMem.DeleteDC();
 bmpMem.DeleteObject();
 font.DeleteObject();

 return hr;
}

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,所以如果有其他人需要知道它是如何完成的......

HRESULT MyGraph::MixTextOverVMR9(LPCTSTR szText)
{
    // create a bitmap object using GDI, render the text to it accordingly
    // then Sets the bitmap as an alpha bitmap to the VMR9, so that it can be overlayed.    

    HRESULT             hr              = S_OK;
    CBitmap             bmpMem; 
    CFont               font;
    LOGFONT             logicfont;

    CRect               rcText;
    CRect               rcVideo;
    VMR9AlphaBitmap     alphaBmp;

    HWND                hWnd            = this->GetFirstRendererWindow();
    COLORREF            clrText         = RGB(255, 255, 0);
    COLORREF            clrBlack        = RGB(0,0,0);
    HDC                 hdcHwnd         = NULL; 
    CDC                 dcMem;

    LONG                lWidth;
    LONG                lHeight;    


    if( ! m_spVideoRenderer.p )
        return E_NOINTERFACE;

    if( !m_spWindowlessCtrl.p )
        return E_NOINTERFACE;

    if( ! m_spIMixerBmp9.p )
    {       
        m_spIMixerBmp9 = m_spVideoRenderer;

        if( ! m_spIMixerBmp9.p )
            return E_NOINTERFACE;
    }

    // create the font..
    LPCTSTR sFont = _T("Impact");
    memset(&logicfont, 0, sizeof(LOGFONT));
    logicfont.lfHeight          = 24;
    //logicfont.lfWidth         = 24;
    logicfont.lfStrikeOut       = 0;
    logicfont.lfUnderline       = 0;
    logicfont.lfItalic          = FALSE;        
    logicfont.lfWeight          = FW_NORMAL;
    logicfont.lfEscapement      = 0; 
    logicfont.lfCharSet         = ANSI_CHARSET;
    logicfont.lfQuality         = ANTIALIASED_QUALITY;
    logicfont.lfPitchAndFamily  = DEFAULT_PITCH | FF_DONTCARE;

    wcscpy_s( &logicfont.lfFaceName[0], wcslen(sFont)*2, sFont );
    font.CreateFontIndirectW(&logicfont);

    // create a compatible memDC from the video window's HDC
    if( hWnd == NULL )
        return E_FAIL;

    hdcHwnd = GetDC(hWnd);
    dcMem   = CreateCompatibleDC(hdcHwnd);

    // get the required bitmap metrics from the MediaBuffer 
    if( ! SUCCEEDED(m_spWindowlessCtrl->GetNativeVideoSize(&lWidth, &lHeight, NULL, NULL)) )
        return E_FAIL;

    // create a bitmap for the text
    bmpMem.CreateCompatibleBitmap(dcMem.m_hDC, lWidth, lHeight);

    SelectBitmap    (dcMem.m_hDC, bmpMem);  
    SetBkColor      (dcMem.m_hDC, clrBlack);    
    SetBkMode       (dcMem.m_hDC, TRANSPARENT);
    SetTextColor    (dcMem.m_hDC, clrText); 
    SelectFont      (dcMem.m_hDC, font.m_hFont);

    // draw the text
    DrawTextW(dcMem.m_hDC, szText, wcslen(szText), rcText, DT_CALCRECT | DT_NOPREFIX );
    DrawTextW(dcMem.m_hDC, szText, wcslen(szText), rcText, DT_NOPREFIX );

    // Set the alpha bitmap on the VMR9 renderer    
    memset(&alphaBmp, 0, sizeof(VMR9AlphaBitmap));  




    // top left
    alphaBmp.rDest.left     = 0.0f + EDGE_BUFFER;
    alphaBmp.rDest.top      = 0.0f + EDGE_BUFFER;
    alphaBmp.rDest.right    = ((float)rcText.right / (float) lWidth) + EDGE_BUFFER;
    alphaBmp.rDest.bottom   = ((float)rcText.bottom / (float)lHeight) + EDGE_BUFFER;

    // top right
    alphaBmp.rDest.left     = 1.0f - ( (float)rcText.right / (float)lWidth)- EDGE_BUFFER;
    alphaBmp.rDest.top      = 0.0f + EDGE_BUFFER;
    alphaBmp.rDest.right    = 1.0f - EDGE_BUFFER;
    alphaBmp.rDest.bottom   = ((float)rcText.bottom / (float)lHeight) + EDGE_BUFFER;

    /*
    // bottom left
    alphaBmp.rDest.left     = 0.0f + EDGE_BUFFER;
    alphaBmp.rDest.top      = 1.0f - ((float)rcText.bottom / (float)lHeight) - EDGE_BUFFER;
    alphaBmp.rDest.right    = ((float)rcText.right / (float) lWidth) + EDGE_BUFFER;
    alphaBmp.rDest.bottom   = 1.0f - EDGE_BUFFER;
    */

    /*
    // bottom right
    alphaBmp.rDest.left     = 1.0f - ( (float)rcText.right / (float)lWidth)- EDGE_BUFFER;
    alphaBmp.rDest.top      = (float)(lHeight - rcText.bottom) / (float)lHeight - EDGE_BUFFER;
    alphaBmp.rDest.right    = 1.0f - EDGE_BUFFER;
    alphaBmp.rDest.bottom   = 1.0f - EDGE_BUFFER;
    */

    alphaBmp.dwFlags        = VMR9AlphaBitmap_hDC | VMRBITMAP_SRCCOLORKEY;
    alphaBmp.hdc            = dcMem.m_hDC;
    alphaBmp.pDDS           = NULL;
    alphaBmp.rSrc           = rcText;               // rect to copy from the source image   
    alphaBmp.fAlpha         = 0.3f;                 // transparency value (1.0 is opaque, 0.0 is transparent)
    alphaBmp.clrSrcKey      = clrBlack; 
    alphaBmp.dwFilterMode   = MixerPref9_PointFiltering;

    hr = m_spIMixerBmp9->SetAlphaBitmap(&alphaBmp);

    DeleteDC(hdcHwnd);
    dcMem.DeleteDC();
    bmpMem.DeleteObject();
    font.DeleteObject();

    return hr;
}