Click here to Skip to main content
16,020,519 members
Articles / Desktop Programming / MFC
Article

Showing an animated image over running video

Rate me:
Please Sign up or sign in to vote.
3.38/5 (10 votes)
15 Sep 20065 min read 294.3K   5.1K   87   20
An easy class which hides all nastiness of DirectShow, and helps in showing an image over playing video, and you can also control the image's transparency. Briefly described is how to do this all.

Sample Image - VideoPicture.jpg

Introduction

Displaying anything over playing video does not seem like an easy task. Here in this article, I tried to display a picture over running video. Not a static image, but now in this updated article, it animates that image.

Updates

I updated my cVideo class to show an image animating. Not only this, but now you can control this image's transparency level also. See "Peeking Inside DirectShow" below.

Background

Displaying a picture over video requires some insight of DirectShow and how to build a filter graph. And, adding custom filters in the graph like VMR9 (video mixing renderer). This VMR9 is the key, it is the renderer which allows us to display a picture over video.

Building Environment

All applications which want to use DirectShow must include the header Dshow.h, and use the library Strmiids.lib.

Peeking Inside DirectShow

The basic force behind displaying an image over a video is the interface IVMRMixerBitmap9. Basically, this interface only has three member functions.

  • GetAlphaBitmapParameters()
  • SetAlphaBitmap()
  • UpdateAlphaBitmapParameters()

The other basic thing is a structure VMR9AlphaBitmap. This is basically used to convey data among functions. Some of the members of VMR9AlphaBitmap which are discussed here are given below:

DWORD              dwFlags;
HDC                hdc;
RECT               rSrc;
VMR9NormalizedRect rDest;
FLOAT              fAlpha;
COLORREF           clrSrcKey;

Now comes the point of how to work with them. Let us see how to initialize the thing for the first time. First of all, we need to know:

  • the handle to the device context hDC in which we have selected (SelectObject) the image,
  • the other important thing is the dimensions of the image,
  • and the third thing which is required is where to show the image on the video (a rect),
  • a transparency level, which tells how much transparent the image will be on the video.
  • a colorkey if you want to hide the background color of the image; set it to the color of the background; it is not a must to hide only the background, you can give any color value, and the given color will be painted as transparent on the video,
  • and at last, the set flags of the value which we have filled.

Now every thing is OK, just call SetAlphaBitmap().

For more insights, see my blog.

Basic Initialization

First of all, we need to create an object of the filter graph manager (the filter graph manager is used to control the filters and the data flow). This process is done by calling CoCreateInstance(). This way, we create an object of the filter graph manager and also get a pointer to the IGraphBuilder interface. This interface is then used for building a custom filter graph (the filter graph is the full set of DirectShow filters to play a media file).

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
IID_IGraphBuilder, (void **)&pGraph);
After creating the filter graph manager, the other important issue is the addition of VMR9 in the filter graph. But before addition, we need to create it, and after creation, we will add that filter (VMR9) to our filter graph.
CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC,
IID_IBaseFilter, (void**)&pVmr);
pGraph->AddFilter(pVmr, L"Video");
Now we need to configure the VMR9 to our custom needs. Such as here, we are setting it to show the video in our provided window, setting the video position.
pVmr->QueryInterface(IID_IVMRFilterConfig9, (void**)&pConfig);
pConfig->SetRenderingMode(VMR9Mode_Windowless);
pVmr->QueryInterface(IID_IVMRWindowlessControl9, (void**)&pWC);
pWC->SetVideoPosition(NULL, pRect);
pWC->SetVideoClippingWindow(pParentWnd->m_hWnd);

The following IVMRMixerBitmap9 is the interface which provides us the facility to show an image over a video. And bmpInfo is a structure which holds the data about our image which we want to show over the video. Here for the first time, we are initializing it to have all zeros.

pWC->QueryInterface(IID_IVMRMixerBitmap9, (LPVOID *)&pBmp);
ZeroMemory(&bmpInfo, sizeof(bmpInfo) );

The following are the interfaces which are very necessary in any DirectShow application, because they provide the facility to control the data flow with IMediaControl, and notifies our application about any important event that occurs. For example, the file end reached, the interface which provides this facility is IMediaEventEx. With this interface, we need to set the window which we want to be notified. And another important interface is IMediaSeeking which provides the facility of seeking in the media file.

pGraph->QueryInterface(IID_IMediaControl, (void **)&pMC);
pGraph->QueryInterface(IID_IMediaEventEx, (void **)&pME);
pME->SetNotifyWindow ( ( OAHWND ) pParentWnd->GetParent()->m_hWnd, 
WM_GRAPHNOTIFY, 0 ) ;
pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pMS);
Now create the custom filter graph. And then run it. After this, the video will start playing in our given window.
pGraph->RenderFile(mFileToPlay, NULL);
pMC->Run();

Displaying the Image

The things we need to know are handle to the device context in which the image is selected, image size, the color value of the background of the image if you want to make the background (of the image) transparent (known as colorkey). Let us start now. First, get the device context of the window on which to play the video. Now we need another device context, which must be compatible with the video window device context, and now select the desired image in that device context.

CDC * pdc = GetDC();
CDC mCompatibleDC;
mCompatibleDC.CreateCompatibleDC(pdc);
mCompatibleDC.SelectObject(hBitmap);
CRect reSrc(0,0,mBitmapWidth,mBitmapHeight);

Now the actual work of displaying the image starts. Initialize the bmpInfo structure with the desired values, e.g., set the flags. Set the device context and the source rectangle, which is the image size.

bmpInfo.dwFlags |= VMRBITMAP_HDC;
bmpInfo.hdc = pDC->m_hDC;
bmpInfo.rSrc = rectSize; // Size of the image

Set the destination rectangle, which is the portion on the screen where to show the image.

// rDest specifies the destination rectangle in composition space (0.0f to 1.0f)
bmpInfo.rDest.right = 1.0f;
bmpInfo.rDest.left = 1.0f - 0.3;
bmpInfo.rDest.top =1.0 - 0.3;
bmpInfo.rDest.bottom = 1.0f;
Set the transparency level.
// Set the transparency value (1.0 is opaque, 0.0 is transparent).
bmpInfo.fAlpha = 0.0;

Set the colorkey value and its flag. Here it is set as Green color. It means any green color on the image will be treated as transparent.

// Set the COLORREF so that the bitmap outline will be transparent
bmpInfo.dwFlags |= VMRBITMAP_SRCCOLORKEY;
bmpInfo.clrSrcKey = RGB(0, 255, 0);
pBmp->SetAlphaBitmap(&bmpInfo); 

Using the Code

I tried to keep things as simple as possible. I built a class cVideo. It is this class which hides all complexities from you. You just call this class's methods, and every thing else is handled by this class. 

This class has following methods:

void InitInterfaces(BSTR mFileToPlay, CWnd* pParentWnd, CRect* pRect);
void Clean(void);
void Play(void);
void ShowImage(CDC* pDC, CRect rectSize);
void HideImage(void);
void SetTransparency( int tansparencyLevel )
void Animate();
  • InitInterfaces() hides all the mysteries of DirectShow graph building.
  • play(), as the name suggests, plays a file.
  • ShowImage() just provides the device context's pointer (CDC* pDC) in which you have selected the picture to be shown.
  • HideImage() just hides the shown image.
  • SetTransparency(int transparencyLevel) controls the transparency level of the image over the video.
  • Animate() updates the image showing the rectangle, simulating animation.
  • at last, Clean() releases the DirectShow interfaces.

History

  • Updated 16 Sep 2006 - Now it describes every thing clearly.
  • Updated 15 Sep 2006 - Added animated image and transparency control.
  • 09 Sep 2006 - First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Pakistan Pakistan
tanvon malik ( real name Tanveer Ahmad )I am a CNC Programmer, cnc setter, cnc operator. want to know about me visit my websites.
CNC Programming
CNC Manuals
DXF & GCode Files with Online Viewers
Komment.me

I been in Switzerland MAG former +FMS+ for CNC training.


Most interesting technologies I like COM MFC DirectShow such as filter development. I am from Pakistan.
Have worked on projects mostly related video capturing, video data processing and real time object tracking on videos. For these I have worked on projects which use "Open CV Library". Which is mostly used for capturing data and its processing.

Comments and Discussions

 
QuestionCLSID_VideoMixingRenderer9 throwing error class not register , Directx 11 installed Pin
Member 131913978-Jun-17 2:39
Member 131913978-Jun-17 2:39 
GeneralI appreciate the time you have taken and thank you. I do have a question [modified] Pin
MicroImaging24-Jan-11 16:43
MicroImaging24-Jan-11 16:43 
GeneralMy vote of 4 Pin
hpokai14-Nov-10 19:45
hpokai14-Nov-10 19:45 
General我有疑问 Pin
Member 66848413-Nov-09 21:10
Member 66848413-Nov-09 21:10 
GeneralRe: 我有疑问 Pin
Aric Wang5-Feb-10 4:30
Aric Wang5-Feb-10 4:30 
QuestionIVMRMixerBitmap::SetAlphaBitmap problem! help me Pin
jessiepan978-May-09 21:30
jessiepan978-May-09 21:30 
QuestionCan you convert your code to a wmp plugin? [modified] Pin
sunny_chn1-Jun-08 2:46
sunny_chn1-Jun-08 2:46 
Generaloverlay two different images at two different position Pin
san07629-May-08 1:12
san07629-May-08 1:12 
GeneralVMR9AlphaBitmap problem Pin
JERAWAT19-Mar-08 21:02
JERAWAT19-Mar-08 21:02 
GeneralRe: VMR9AlphaBitmap problem Pin
tanvon malik6-Sep-08 22:23
tanvon malik6-Sep-08 22:23 
Questionhow can I use "CLSID_VideoMixingRenderer9" in smart device project. Pin
Suman Kumar Sikdar4-Apr-07 23:28
Suman Kumar Sikdar4-Apr-07 23:28 
GeneralReform you article Pin
NormDroid15-Sep-06 20:34
professionalNormDroid15-Sep-06 20:34 
GeneralRe: Reform you article Pin
tanvon malik16-Sep-06 0:45
tanvon malik16-Sep-06 0:45 
GeneralRe: Reform you article Pin
NormDroid17-Sep-06 20:41
professionalNormDroid17-Sep-06 20:41 
Generalcool Pin
koools15-Sep-06 19:46
koools15-Sep-06 19:46 
GeneralRe: cool Pin
tanvon malik6-Sep-08 22:16
tanvon malik6-Sep-08 22:16 
QuestionHow to do the same with DirectX ? Pin
Artem Moroz12-Sep-06 3:31
Artem Moroz12-Sep-06 3:31 
Hello!

Do you have any information about how to do the same with DirectX application? I need to draw bitmap on the existing DirectX surface (e.g. another application)



Regards,
MAV
GeneralDirectShow Pin
enax2212-Sep-06 3:29
enax2212-Sep-06 3:29 
GeneralDirectX, DirectShow Pin
enax2211-Sep-06 21:36
enax2211-Sep-06 21:36 
GeneralRe: DirectX, DirectShow Pin
tanvon malik11-Sep-06 22:36
tanvon malik11-Sep-06 22:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.