複合イメージにアプリ提供のビットマップを表示する
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]
アプリケーションでは、VMR のミキシング モードを使用して、アルファ ブレンド チャネルロゴ、ユーザー インターフェイス、または広告をビデオ四角形内で部分的または完全に表示できます。 ブレンドはグラフィックス プロセッサによってハードウェアで実行されるため、Video Stream の再生パフォーマンスへの影響は最小限であり、検出可能なちらつきや引き裂きアーティファクトはありません。 アプリケーションは、必要に応じて頻繁に表示されるイメージを変更できます。 DirectShow フィルター グラフが実行中の状態の場合にのみ、変更が画面に反映されることに注意してください。
VMR は、そのミキサー コンポーネントを使用して、ビットマップを複合イメージにオーバーレイします。 VMR-7 では、1 つのビデオ ストリームしかない場合でも、アプリケーションは VMR にミキサーの読み込みを強制する必要があります。 VMR-9 では、既定でミキサーが読み込まれるため、これは必要ありません。
静的ビットマップ イメージをビデオ ストリームとブレンドするために、アプリケーションは VMR を作成してグラフに追加し、 IVMRFilterConfig::SetNumberOfStreams を呼び出します。 この関数に渡される値は、VMR で作成する必要がある入力ピンの数を識別します。 アプリケーションでは、1 ~ MAX_MIXER_STREAMSの任意の値を指定できます。1 の値を指定することは、アプリケーションが単一のビデオ ストリームのみを表示する場合に有効です。 VMR-7 には既定で 1 つの入力ピンがありますが、このメソッドを強制的に呼び出してミキサー コンポーネントを読み込む必要があります。 (VMR-9 はミキサーを読み込み、既定で 4 つのピンを設定します)。
ビットマップを設定するには、VMR-7 の IVMRMixerBitmap インターフェイスまたは VMR-9 の IVMRMixerBitmap9 インターフェイスを使用します。
ビットマップは、GDI デバイス コンテキスト (hDC) へのハンドルまたは DirectDraw Surface インターフェイスによって指定できます。 アプリケーションが画像に埋め込まれたアルファ情報 (ピクセルごとのアルファとも呼ばれます) を含める場合は、イメージ データを DirectDraw Surface インターフェイスに配置する必要があります。 これは、現在、GDI デバイス コンテキストを使用してピクセル単位のアルファ情報を配置できないためです。 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 サンプル アプリケーションで示されています。
ビットマップ イメージを使用した単純なアニメーションの作成
単純なアニメーション化されたビットマップ ロゴを作成するには、次の図に示すように、すべてのビットマップ "フレーム" を 1 つのイメージに配置します。
最初に IVMRMixerBitmap::SetAlphaBitmap を使用してビットマップを設定する場合、ビットマップが HDC 内にある場合は、VMRALPHABITMAP 構造体の rSrc フィールドを設定して、HDC 内のビットマップ全体のサイズを指定します。 構造体の上と左のメンバーは 0 に設定され、左右のメンバーはビットマップの幅と高さになります。 ビットマップが DirectDraw サーフェス内にある場合は、サーフェスのサイズがわかっているので、このメソッドで rSrc を指定する必要はありません。
IVMRMixerBitmap::UpdateAlphaBitmapParameters を呼び出すときは、HDC ビットマップと DirectDraw ビットマップの両方に rSrc メンバーを使用して、表示するイメージ内の特定のフレームまたは四角形を指定し、dwFlags メンバーに VMRBITMAP_SRCRECT フラグを設定します。
関連トピック