Partager via


Afficher une bitmap fournie par l’application sur l’image composite

[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngineet audio/vidéo capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et capture audio/vidéo dans Media Foundation au lieu de directShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]

Les applications peuvent utiliser le mode de mixage de VMR pour afficher des logos de canal mixte alpha, une interface utilisateur ou des publicités partiellement ou complètement dans le rectangle vidéo. Étant donné que le mélange est effectué dans le matériel par le processeur graphique, il y a un impact minimal sur les performances de lecture du flux vidéo, et il n’y a pas d’artefacts détectables de scintillement ou de déchirure. Les applications peuvent modifier l’image affichée aussi fréquemment qu’elles le souhaitent. Notez que les modifications ne sont répercutées que sur l’écran lorsque le graphique de filtre DirectShow est dans l’état en cours d’exécution.

VmR utilise son composant de mélangeur pour superposer la bitmap sur l’image composite. Avec VMR-7, l’application doit forcer vmR à charger son mélangeur, même s’il n’existe qu’un seul flux vidéo. Cela n’est pas nécessaire avec vmR-9, car il charge son mélangeur par défaut.

Pour fusionner une image bitmap statique avec le flux vidéo, l’application crée vmR et l’ajoute au graphique, puis appelle IVMRFilterConfig ::SetNumberOfStreams. La valeur transmise à cette fonction identifie le nombre d’épingles d’entrée que vmR doit créer. Les applications peuvent spécifier n’importe quelle valeur comprise entre 1 et MAX_MIXER_STREAMS ; la spécification d’une valeur 1 est valide si l’application a l’intention d’afficher un seul flux vidéo. Même si vmR-7 a une seule broche d’entrée par défaut, cette méthode doit être appelée pour la forcer à charger son composant de mélangeur. (VmR-9 charge son mélangeur et configure quatre broches par défaut.)

Pour définir la bitmap, utilisez l’interface IVMRMixerBitmap sur vmR-7 ou l’interface IVMRMixerBitmap9 sur VMR-9.

La bitmap peut être spécifiée par un handle vers un contexte d’appareil GDI (hDC) ou par une interface DirectDraw Surface. Si l’application souhaite que l’image contienne des informations alpha incorporées (également appelées alpha par pixel), elle doit placer les données d’image dans une interface DirectDraw Surface. Cela est dû au fait qu’il n’est actuellement pas possible de placer des informations alpha par pixel avec un contexte d’appareil GDI. La surface DirectDraw doit être RVB32 ou ARGB32 et doit de préférence être une surface de mémoire système. Il n’est pas nécessaire que les dimensions de surface soient une puissance de 2.

VmR permet aux applications de spécifier l’emplacement et une valeur de transparence globale pour l’image. Le code suivant montre comment transmettre des données d’image à vmR pour la fusion suivante :

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;
}

Les concepts abordés dans cette rubrique sont présentés dans l’exemple d’application VMRPlayer Sample.

création d’animations simples avec le d’image bitmap

Pour créer un logo bitmap animé simple, placez toutes les images bitmap « frames » dans une seule image, comme illustré dans l’illustration suivante.

bande d’images vmr

Lorsque vous définissez la bitmap initialement à l’aide de IVMRMixerBitmap ::SetAlphaBitmap, si la bitmap se trouve dans un HDC, définissez le champ rSrc de la structure VMRALPHABITMAP pour spécifier la taille de l’image bitmap entière dans hdC. Le supérieur et membres gauche de la structure sont définis sur 0, et les droite et membres inférieurs sont la largeur et la hauteur de la bitmap. Si la bitmap se trouve dans une surface DirectDraw, la taille de la surface est connue, il n’est donc pas nécessaire de spécifier rSrc dans cette méthode.

Lorsque vous appelez IVMRMixerBitmap ::UpdateAlphaBitmapParameters, utilisez le membre rSrc pour les bitmaps HDC et DirectDraw, pour spécifier le cadre ou le rectangle particulier dans l’image que vous souhaitez afficher, puis définissez l’indicateur VMRBITMAP_SRCRECT dans le membre dwFlags.

à l’aide du mode de mixage VMR