2012-08-05 30 views

回答

1

我能夠用Windows GDI調用完成此操作。我創建的MFT具有RGB32輸入/輸出類型,它允許我從Bitmap對象中複製/從中複製。我將我想要與文本重疊的框架部分複製到我創建的Windows位圖中,繪製文本,然後將其複製回IMFMediaBuffer。這裏是我的代碼:

#define BREAK_ON_FAIL(val) { if (FAILED(hr = (val))) { break; } } 

HRESULT AddOverlay(IMFSample* pSample) 
{ 
    HRESULT hr = S_OK; 
    IMFMediaBuffer * pBuffer; 
    HDC hDC, hMemDC; 
    HBITMAP hBitmap, hOldBitmap; 

    do 
    { 
     BYTE * pBufferData; 
     UINT32 nWidth, nHeight; 
     BITMAPV5HEADER bi; 
     BYTE * pBitmapData; 
     UINT32 nXOffset, nYOffset; 
     RECT OverlayRect; 
     OverlayRect.left = 0; 
     OverlayRect.top = 0; 
     OverlayRect.right = 400; 
     OverlayRect.bottom = 32; 
     DWORD nOverlayWidth = OverlayRect.right - OverlayRect.left; 
     DWORD nOverlayHeight = OverlayRect.bottom - OverlayRect.top; 
     LONG lFrameStride; 

     // Get the frame dimensions and stride 
     MFGetAttributeSize(m_pInputType, MF_MT_FRAME_SIZE, &nWidth, &nHeight); 
     m_pInputType->GetUINT32(MF_MT_DEFAULT_STRIDE, (UINT32*)&lFrameStride)) 

     // Setup offset for the overlay area into the video frame 
     nXOffset = (nWidth - nOverlayWidth)/2; 
     nYOffset = nOverlayHeight-1; 

     // Set up the bitmap header 
     ZeroMemory(&bi, sizeof(BITMAPV5HEADER)); 
     bi.bV5Size   = sizeof(BITMAPV5HEADER); 
     bi.bV5Width   = nOverlayWidth; 
     // If the stride is negative, the bitmap is bottom-up, which is designated by a negative height 
     bi.bV5Height  = (lFrameStride > 0) ? nOverlayHeight : -(LONG)nOverlayHeight; 
     bi.bV5Planes  = 1; 
     bi.bV5BitCount  = 32; 
     bi.bV5Compression = BI_RGB; 
     // The following mask specification specifies a supported 32 BPP 
     // alpha format for Windows XP. 
     bi.bV5RedMask  = 0x00FF0000; 
     bi.bV5GreenMask  = 0x0000FF00; 
     bi.bV5BlueMask  = 0x000000FF; 
     bi.bV5AlphaMask  = 0xFF000000; 

     // Create a DIB section with an alpha channel, along with 
     // a memory device context 
     hDC = GetDC(NULL); 
     hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pBitmapData, NULL, 0); 
     hMemDC = CreateCompatibleDC(hDC); 
     ReleaseDC(NULL, hDC); 

     // Lock the media buffer for our use 
     BREAK_ON_FAIL(pSample->GetBufferByIndex(0, &pBuffer)); 
     BREAK_ON_FAIL(pBuffer->Lock(&pBufferData, NULL, NULL)); 

     // Copy the video frame to the bitmap (to support transparency) 
     MFCopyImage(pBitmapData, nOverlayWidth*sizeof(RGBQUAD), 
      pBufferData + nYOffset*abs(lFrameStride) + nXOffset*sizeof(RGBQUAD), lFrameStride, 
      nOverlayWidth*sizeof(RGBQUAD), nOverlayHeight); 

     // Draw on the bitmap 
     hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); 
     //FillRect(hMemDC, &OverlayRect, WHITE_BRUSH); 
     SetTextColor(hMemDC, RGB(255,0,0)); 
     SetBkMode(hMemDC, TRANSPARENT); 
     DrawText(hMemDC, _T("Hello World!"), 12, &OverlayRect, DT_CENTER); 
     SelectObject(hMemDC, hOldBitmap); 

     // Copy the bitmap to the buffer 
     MFCopyImage(pBufferData + nYOffset*abs(lFrameStride) + nXOffset*sizeof(RGBQUAD), lFrameStride, 
      pBitmapData, nOverlayWidth*sizeof(RGBQUAD), 
      nOverlayWidth*sizeof(RGBQUAD), nOverlayHeight); 

     BREAK_ON_FAIL(pBuffer->Unlock()); 

    } while(false); 

    DeleteDC(hMemDC); 
    DeleteObject(hBitmap); 
    SafeRelease(&pBuffer); 

    return hr; 
} 

參考文獻:

相關問題