在复合图像上显示应用提供的位图
[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayer、 IMFMediaEngine 和 音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
应用程序可以使用 VMR 的混合模式在视频矩形中部分或完全显示 alpha 混合通道徽标、用户界面或播发。 由于混合由图形处理器在硬件中执行,因此对视频流的播放性能的影响最小,并且没有可检测到的闪烁或撕裂项目。 应用程序可以根据需要更改显示的图像。 应注意的是,只有当 DirectShow 筛选器图处于运行状态时,更改才会反映在屏幕上。
VMR 使用其混音器组件将位图覆盖到复合图像上。 使用 VMR-7 时,应用程序必须强制 VMR 加载其混音器,即使只有一个视频流也是如此。 VMR-9 不需要这样做,因为它默认加载其混音器。
若要将静态位图图像与视频流混合,应用程序会创建 VMR 并将其添加到图形,然后调用 IVMRFilterConfig::SetNumberOfStreams。 传递给此函数的值标识 VMR 应创建的输入引脚数。 应用程序可以指定介于 1 和 MAX_MIXER_STREAMS 之间的任何值;如果应用程序只打算显示单个视频流,则指定值为 1 是有效的。 尽管 VMR-7 默认具有单个输入引脚,但必须调用此方法以强制它加载其混音器组件。 (VMR-9 默认加载其混音器并设置四个引脚。)
若要设置位图,请使用 VMR-7 上的 IVMRMixerBitmap 接口或 VMR-9 上的 IVMRMixerBitmap9 接口。
位图可以通过 GDI 设备上下文的句柄 (hDC) 或 DirectDraw Surface 接口指定。 如果应用程序希望图像包含嵌入的 alpha 信息 (也称为每像素 alpha) 它必须将图像数据放在 DirectDraw Surface 接口中。 这是因为目前无法使用 GDI 设备上下文放置每像素 alpha 信息。 DirectDraw 图面必须是 RGB32 或 ARGB32,最好是系统内存图面。 表面尺寸不必为 2 的幂。
VMR 允许应用程序指定映像的位置和整体透明度值。 以下代码演示如何将图像数据向下传递到 VMR,以便进行后续混合:
HRESULT BlendApplicationImage(
HWND hwndApp,
IVMRWindowlessControl* pWc,
HBITMAP hbm
)
{
LONG cx, cy;
HRESULT hr;
hr = pWc->GetNativeVideoSize(&cx, &cy, NULL, NULL);
if (FAILED(hr))
return hr;
HDC hdc = GetDC(hwndApp);
if (hdc == NULL)
{
return E_FAIL;
}
HDC hdcBmp = CreateCompatibleDC(hdc);
ReleaseDC(hwndApp, hdc);
if (hdcBmp == NULL)
{
return E_FAIL;
}
BITMAP bm;
if (0 == GetObject(hbm, sizeof(bm), &bm))
{
DeleteDC(hdcBmp);
return E_FAIL;
}
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcBmp, hbm);
if (hbmOld == 0)
{
DeleteDC(hdcBmp);
return E_FAIL;
}
VMRALPHABITMAP bmpInfo;
ZeroMemory(&bmpInfo, sizeof(bmpInfo) );
bmpInfo.dwFlags = VMRBITMAP_HDC;
bmpInfo.hdc = hdcBmp;
// Show the entire bitmap in the top-left corner of the video image.
SetRect(&bmpInfo.rSrc, 0, 0, bm.bmWidth, bm.bmHeight);
bmpInfo.rDest.left = 0.f;
bmpInfo.rDest.top = 0.f;
bmpInfo.rDest.right = (float)bm.bmWidth / (float)cx;
bmpInfo.rDest.bottom = (float)bm.bmHeight / (float)cy;
// Set the transparency value (1.0 is opaque, 0.0 is transparent).
bmpInfo.fAlpha = 0.2f;
IVMRMixerBitmap* pBmp;
hr = pWc->QueryInterface(IID_IVMRMixerBitmap, (LPVOID *)&pBmp);
if (SUCCEEDED(hr))
{
pBmp->SetAlphaBitmap(&bmpInfo);
pBmp->Release();
}
DeleteObject(SelectObject(hdcBmp, hbmOld));
DeleteDC(hdcBmp);
return hr;
}
VMRPlayer 示例应用程序中演示了本主题中讨论的概念。
使用位图图像创建简单动画
若要创建简单的动画位图徽标,请将所有位图“帧”放入单个图像中,如下图所示。
最初使用 IVMRMixerBitmap::SetAlphaBitmap 设置位图时,如果位图位于 HDC 中,请设置 VMRALPHABITMAP 结构的 rSrc 字段以指定 HDC 中整个位图的大小。 结构的 顶部 和 左侧 成员设置为 0, 右侧 和 底部 成员是位图的宽度和高度。 如果位图位于 DirectDraw 图面中,则图面的大小是已知的,因此无需在此方法中指定 rSrc。
调用 IVMRMixerBitmap::UpdateAlphaBitmapParameters 时,对 HDC 和 DirectDraw 位图使用 rSrc 成员,指定要显示的图像中的特定帧或矩形,并在 dwFlags 成员中设置VMRBITMAP_SRCRECT标志。
相关主题