- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
如何在 IMFMediaBuffer 对象上绘制文本,并将其写出到另一个 IMFMediaBuffer 对象?
上下文是我正在构建 MFT,最初我尝试使用 Direct2D 和 Direct3D11 来实现此目的,但无济于事。
最佳答案
我能够通过 Windows GDI 调用完成此操作。我创建的 MFT 具有 RGB32 输入/输出类型,这允许我复制到位图对象或从中复制。我将要用文本覆盖的框架部分复制到我创建的 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;
}
引用资料:
关于windows - 在 Windows 8 媒体基础转换中在 IMFMediaBuffer 上绘制文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11813804/
DirectX 媒体对象 (DMO) documentation建议,为了提高效率,保存媒体样本的缓冲区(支持 IMediaBuffer 接口(interface))应该被合并而不是不断地创建/销毁:
我有一个在 Unity 5.2 上使用 Hololens 可定位相机的计算机视觉插件。我使用 UnityEngine.XR.WSA.WebCam.PhotoCaptureFrame 类,在最高分辨率下
我正在尝试将一个连续的缓冲区拆分为 3 个字节的 channel (RGB)。这是我让缓冲区充满图像的实际工作流程: 设置源读取器 (MFVideoFormat_RGB32) 接收视频格式信息 读取第
如何在 IMFMediaBuffer 对象上绘制文本,并将其写出到另一个 IMFMediaBuffer 对象? 上下文是我正在构建 MFT,最初我尝试使用 Direct2D 和 Direct3D11
我是一名优秀的程序员,十分优秀!