다음을 통해 공유


복합 이미지에 앱 제공 비트맵 표시

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngineMedia Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드에서 DirectShow 대신 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

애플리케이션은 VMR의 혼합 모드를 사용하여 비디오 사각형 내에서 알파 혼합 채널 로고, 사용자 인터페이스 또는 광고를 부분적으로 또는 완전히 표시할 수 있습니다. 혼합은 그래픽 프로세서에 의해 하드웨어에서 수행되므로 비디오 스트림의 재생 성능에 최소한의 영향을 미치며 감지 가능한 깜박임 또는 찢어지는 아티팩트가 없습니다. 애플리케이션은 원하는 만큼 자주 표시되는 이미지를 변경할 수 있습니다. DirectShow 필터 그래프가 실행 중 상태인 경우에만 변경 내용이 화면에 반영됩니다.

VMR은 혼합기 구성 요소를 사용하여 비트맵을 복합 이미지에 오버레이합니다. VMR-7을 사용하면 단일 비디오 스트림만 있는 경우에도 애플리케이션에서 VMR이 해당 믹서의 부하를 강제로 로드해야 합니다. 기본적으로 믹서가 로드되므로 VMR-9에서는 필요하지 않습니다.

정적 비트맵 이미지를 비디오 스트림과 혼합하기 위해 애플리케이션은 VMR을 만들고 그래프에 추가한 다음 IVMRFilterConfig::SetNumberOfStreams를 호출합니다. 이 함수에 전달된 값은 VMR이 만들어야 하는 입력 핀 수를 식별합니다. 애플리케이션은 1에서 MAX_MIXER_STREAMS 사이의 값을 지정할 수 있습니다. 애플리케이션이 단일 비디오 스트림만 표시하려는 경우 값 1을 지정하는 것이 유효합니다. VMR-7에는 기본적으로 단일 입력 핀이 있더라도 믹서 구성 요소를 강제로 로드하려면 이 메서드를 호출해야 합니다. (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 샘플 애플리케이션 에서 설명합니다.

비트맵 이미지를 사용하여 간단한 애니메이션 만들기

간단한 애니메이션 비트맵 로고를 만들려면 다음 그림과 같이 모든 비트맵 "프레임"을 단일 이미지에 넣습니다.

vmr 이미지 스트립

처음에 IVMRMixerBitmap::SetAlphaBitmap을 사용하여 비트맵을 설정할 때 비트맵이 HDC에 있는 경우 VMRALPHABITMAP 구조체의 rSrc 필드를 설정하여 HDC 내에서 전체 비트맵의 크기를 지정합니다. 구조체의 위쪽왼쪽 멤버는 0으로 설정되고 오른쪽아래쪽 멤버는 비트맵의 너비와 높이입니다. 비트맵이 DirectDraw 표면에 있는 경우 표면의 크기를 알 수 있으므로 이 메서드에서 rSrc를 지정할 필요가 없습니다.

IVMRMixerBitmap::UpdateAlphaBitmapParameters를 호출할 때 HDC 및 DirectDraw 비트맵 모두에 대해 rSrc 멤버를 사용하여 표시하려는 이미지 내의 특정 프레임 또는 사각형을 지정하고 dwFlags 멤버에서 VMRBITMAP_SRCRECT 플래그를 설정합니다.

VMR 혼합 모드 사용