Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

Your Own AVI Shop

5.00/5 (4 votes)
8 Feb 2024CPOL5 min read 10.7K   657  
Build up our own AVI editing application and explore some fun techniques using simple code additions

Walking RoundAbout

Introduction

Modifying AVI files can always be done using popular media programs available online, but these programs work without allowing you to add your own magic.

In this article, we’ll build our own AVI editing application and explore some fun techniques using simple code additions.

Background

This project is destined for the intermediate level MFC developers. The MSVS-2015 pro installed is
a prerequisite to proper text comprehension.

Demo Explanations

As a sample, the long-suffering well-known “Beatles” gif selected: only the lazy would not try to “improve” this video. Start MyAviShop.exe in the MyAviShopDemo directory enclosed. Just follow step by step the instructions below and after completion, you’ll have a comprehensive idea of the features of the program.

1.1 AVI Open and Controls

Select the DemoSample/Beatles_01.avi file with the menu command File->Open Avi. The use of some controls demonstrated in the sample below:

AVI Open and Controls

1.2 Mask of the Object Detected Handling

Select menu Polygon->New Polygon and number of points expected in your new mask polygon. Move and resize all the polygon of the object detected using the standard Rechittest procedures (just pay attention to the Keep Ratio checkbox condition):

Mask Polygon Edit

In the sample provided, this job already has been done; therefore select menu Polygon->Delete All Polygons, select menu Polygon->Open Polygonset and select Beatles_a.pl2 file; Next, use menu Polygon->Mask PolygonSet to create the list of the masked images of the object detected with the one-tone color background which may be superposed above any AVI video:

Save Masked Image of Polygon

In the sample provided, this job already has been done for every person and fixed in the files as Beatles_01_of_Beatles_a.mpl for a, b, c, d masks.

Now we shall arrange the copy of people moving in the one-tone color background:

Set of Mask AVI

  • Open Blank.avi as a target with the menu File Avi->Open Avi command;
  • Capture masks for Blank.avi of Beatles_a.avi, Beatles_b.avi, Beatles_c.avi, Beatles_d.avi. with the menu Mask Edit->MaskCapture and open *.mpl file corresponding.
  • Save current AVI with File Avi->Save as Avi:

Create Blank One Tone Color AVI

The results you may see in Beatles_Blank.avi:

One Tone Color AVI

Now we shall arrange the mask of people moving in the changed order and save current AVI with File Avi->Save as Avi (results you may see in Beatles_Blank_r.avi):

Change the Order of People

Next, apply this mask to the empty street (the results you may see in Beatles_r.avi):

In this article title AVI, people seemed like a walking roundabout. And this is the smallest trick possible to arrange:

Create RoundAbout Walking

1.3 Screen Capture

Call menu File Images->Screen Capture to pick up images from the screen; (Result in the ScreenCap February 02_2019_15_56.avi file):

Screen Capture

2. Project Source Storage and Building Notes

The source files of the project are located in two directories:

MyAviShop – created with the standard MFC AppWizard:

  • MyAviShop.cpp, MyAviShopDoc.cpp, MyAviShopView.cpp, MainFrm.cpp, MyAviShop.rc, resource.h - created with the standard MFC AppWizard and all the messages handling procedures have been arranged also with MFC standards;
  • Splitter.cpp have been inserted instead of the originally MFC created ChildFrm.cpp;
  • All the dialogs’ concerned classes created with the standard MFC AppWizard;
  • MaskHandle.cpp and MaskUnit.cpp – created by the author for the mask images handling;

GlobUse – the program set of the procedures which are independent of the Main Project and may be included in any MFC project as required:

  • EasyAVI.cpp - borrowed from the article "Easy AVI" by Andy Bantly;
  • MyRectTrack.cpp - has been created by the author for the project provided in order to perform flexible operations with the Mask Recttrack;
  • Another code has been earlier created by the author and has been already used with other projects as well as CodeProject including.

Even if you are first time working with MSVS, just select menu Debug->Start without debugging and the project MyAviShop should start building and working.

3. Codes Explanations

All the Menu and Controls handling Commands have been done with standard MFC AppWizard technologies. Therefore, I feel nothing to explain better than in the standard tutorials. Just some points that I’ve developed myself.

3.1 Mask Visualization

The mask enclosed in some polygon area may be shredded out using two graphical contests (black-white and some buffer):

C++
//if number points in polygon:    
if (m_pCurPolygon->m_PointList.GetCount() > 2)              //if polygon has some points 
{
	double scale = m_pDoc->m_Scale;
	//fill white some bw contest:
	m_bwDC.BitBlt(tRect.left, tRect.top, tRect.Width(), 
                  tRect.Height(), NULL, 0, 0, WHITENESS);
	//draw black area enclosed with the polygon 
	m_pCurPolygon->DrawBlackStroke(&m_bwDC, Vector_2D(1), 0, 
                   m_pCurPolygon->turnPoint*scale, 0, scale, scale, FALSE, TRUE);
	//revert colors: white polygon with black background 
	m_bwDC.BitBlt(tRect.left, tRect.top, tRect.Width(), 
                  tRect.Height(), NULL, 0, 0, DSTINVERT);
	//put the image into some buf contest:
	pImg->StretchBlt(m_bufDC.m_hDC, m_pixOffSet.x, m_pixOffSet.y, 
                     int(scale * pImg->GetWidth()), int(scale * pImg->GetHeight()));
	//put bw mask from bw contents on to buf contents using SRCAND: 
    //on the buf content we have the mask of the image enclosed with polygon 
    //on the black background: 
	m_bufDC.BitBlt(tRect.left, tRect.top, tRect.Width(), 
                   tRect.Height(), &m_bwDC, 0, 0, SRCAND);
	//fill the final contest with the gray grey color:
	m_memDC.FillRect(tRect, &CBrush(RGB(127, 127, 127)));
	//put the image into some buf contest using SRCAND:we have dimmed image
	pImg->StretchBlt(m_memDC.m_hDC, m_pixOffSet.x, m_pixOffSet.y, 
          int(scale * pImg->GetWidth()), int(scale * pImg->GetHeight()), SRCAND);
	//put the mask from buf contest
	m_memDC.TransparentBlt(tRect.left, tRect.top, tRect.Width(), 
         tRect.Height(), &m_bufDC, tRect.left, tRect.top, tRect.Width(), 
         tRect.Height(), RGB(255, 255, 255));
	//draw polygon iself:
	m_pCurPolygon->DrawSolidStroke(&m_memDC, Vector_2D(1), 0, 
             m_pCurPolygon->turnPoint*scale, 0, scale, scale, FALSE, TRUE);
}
  • The black-white contest to fill with the white color;
  • Draw black area enclosed with the polygon;
  • Revert colors: a white polygon with the black background;
  • Put the original image into buffer contest;
  • Put BW mask from a black-white contest on to buffer contents using SRCAND: on the buffer contest, we have the mask of the image enclosed with the polygon on the black background.

3.2 Mask Recttrack

For the mask handling, some special classes have been inserted:

  • CMyRectTrack – derived from the Polygon_2D class; used for the moving, resizing and rotating of the mask;
  • CMaskUnit - derived from the CObject class; used to store the information of the mask: position, size, an angle of turn, the number in the list of mask images;
  • CMaskHandle - derived from the CObject class; used to manage the list of the CMaskUnit Objects and has the references both to the target list of images and to the mask list of images.

Set of masks drawing procedure as follows:

C++
//for all mask sets captured by this window
for (POSITION pos = m_maskWindowList.GetHeadPosition(); pos != NULL;)
 {
   //select next mask set captured by this window  
   CMyAviShopDoc * pDoc = (CMyAviShopDoc *)m_maskWindowList.GetNext(pos);
   //for all CMackHandle objects obtained by current mask AVI window:
   for (POSITION psn = pDoc->m_maskHandleList.GetHeadPosition(); psn != NULL;)
   {
      //select next CMackHandle object obtained by current mask AVI window:
	CMaskHandle * ptr = (CMaskHandle *)pDoc->m_maskHandleList.GetNext(psn);
	//if current CMackHandle object has the reference to this Window
	if (ptr->m_pAviHost == m_pDoc)
	{
	 //select the CMaskUnit Object corresponding to the 
	 //number of current frame in this window:
	 POSITION psa = ptr->m_maskUnitList.FindIndex(nn);
	 if (psa != NULL)
	 {
	     CMaskUnit * pMsk = (CMaskUnit *)ptr->m_maskUnitList.GetAt(psa);
	     m_pDoc->m_pCurMaskUnit = pMsk;

	    // if CMaskUnit Object found it gives the info
	    //of position, size and angle to Mask RectTrack:
	    m_pMyRectTrack->m_angle = pMsk->m_angle;
	    m_pMyRectTrack->SetRect(pMsk->m_tgtRect);
		
          //Draw  Mask RectTrack if fit: 
	   if (m_pDoc->m_bDrawMaskRect && pMsk->m_number >= 0)
		m_pMyRectTrack->DrawRectTrack(&m_memDC, m_pDoc->m_Scale);
	  else
		m_pMyRectTrack->DrawRectTrack(&m_bwDC, m_pDoc->m_Scale);

	  //Draw mask on to the current image of this window 
	   pMsk->SetMask(&m_memDC, &m_bufDC, &m_bwDC, m_pMyRectTrack, m_pDoc->m_Scale);
	}
	break;
       }//if (ptr->m_pAviHost == this)
    }
}//for (POSITION pos = m_maskWindowList.GetHeadPosition(); pos != NULL;)

4. Your Own Applications Development Using this Project

You may pick up all this project, rename it with the project of my former CodeProject article "MFC Project from Existing Code in One Click" and combine and improve the code as you like.

Or you may pick up any of GlobUse directory files from this project and include it in any MFC project with menu Project->Existing Item.

Or you may simply use the MyAviShop.exe from the demo provided to “improve” any AVI and/or NetWork scene captured.

Your references to my code should be highly appreciated if any.

Discussion

The idea of this article is that the project provided with you may arrange good support to the usual AVI editor programs or even to develop your own AVI Shop program.

And this is the illustration of the CodeProject performance capabilities to help the developers in any solution.

Conclusion, Points of Interest, and Acknowledgements

The gif illustrations have been created with the help of the MyAviShop itself: one session performed the actions while another one "spied" the performance.

This project is the instrument to arrange some tricks and effects as you like having in mind that the codes are open.

Some samples of my earlier versions of this job are available on YouTube/vl2525.

Many thanks to Andy Bantly and Darryl Bryk for their fine job.

History

  • 2nd April, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)