65.9K
CodeProject 正在变化。 阅读更多。
Home

您自己的 AVI 编辑器

2019 年 4 月 2 日

CPOL

5分钟阅读

viewsIcon

11092

downloadIcon

705

创建您自己的 AVI 编辑应用程序,并通过简单的代码添加来探索一些有趣的技巧

Walking RoundAbout

引言

使用市面上流行的媒体程序可以修改AVI文件,但这些程序无法让您加入自己的创意。

在本文中,我们将构建自己的AVI编辑应用程序,并通过一些简单的代码添加来探索有趣的技巧。

背景

本项目适合中级MFC开发者。安装MSVS-2015 pro是正确理解本文的前提。
前提条件是安装了MSVS-2015 pro

演示说明

作为示例,我们选择了饱受摧残的、众所周知的“披头士”gif:只有懒惰的人才不会尝试“改进”这个视频。在 enclosed 的MyAviShopDemo目录中启动MyAviShop.exe。只需按照下面的步骤操作,完成后您将对该程序的功能有一个全面的了解。

1.1 AVI 打开和控件

使用菜单命令File->Open Avi选择DemoSample/Beatles_01.avi文件。下面的示例演示了某些控件的使用。

AVI Open and Controls

1.2 已检测对象的蒙版处理

选择菜单Polygon->New Polygon,并输入新蒙版多边形所需的点数。使用标准的Rechittest过程移动和调整已检测对象的所有多边形(请注意Keep Ratio checkbox条件)。

Mask Polygon Edit

在提供的示例中,这项工作已经完成;因此,选择菜单Polygon->Delete All Polygons,选择菜单Polygon->Open Polygonset并选择Beatles_a.pl2文件;接下来,使用菜单Polygon->Mask PolygonSet创建已检测对象的蒙版图像列表,其背景为单色,可以叠加在任何AVI视频之上。

Save Masked Image of Polygon

在提供的示例中,这项工作已经为每个人完成了,并固定在文件中,如Beatles_01_of_Beatles_a.mpl,用于a, b, c, d蒙版。

现在我们将排列单色背景中移动的人的副本。

Set of Mask AVI

  • 使用菜单File Avi->Open Avi命令打开Blank.avi作为目标文件;
  • 使用菜单Mask Edit->MaskCapture捕获Beatles_a.aviBeatles_b.aviBeatles_c.avi、Beatles_d.avi的Blank.avi蒙版,并打开相应的*.mpl文件。
  • 使用 File Avi->Save as Avi命令保存当前的 AVI。

Create Blank One Tone Color AVI

您可以在Beatles_Blank.avi中看到结果。

One Tone Color AVI

现在我们将排列以改变顺序移动的人的蒙版,并使用File Avi->Save as Avi命令保存当前的 AVI(您可以在Beatles_Blank_r.avi中看到结果)。

Change the Order of People

接下来,将此蒙版应用于空街道(您可以在Beatles_r.avi中看到结果)。

在这个文章的标题 AVI 中,人们看起来像在转圈。这是可能的最小的安排技巧。

Create RoundAbout Walking

1.3 屏幕捕获

调用菜单File Images->Screen Capture从屏幕捕获图像;(结果在ScreenCap February 02_2019_15_56.avi文件中)

Screen Capture

2. 项目源文件存储和构建说明

项目的源文件位于两个目录中:

MyAviShop – 使用标准的MFC AppWizard创建:

  • MyAviShop.cpp, MyAviShopDoc.cpp, MyAviShopView.cpp, MainFrm.cpp, MyAviShop.rc, resource.h - 使用标准的MFC AppWizard创建,所有消息处理程序也使用MFC标准进行安排;
  • Splitter.cpp已被插入,取代了最初由MFC创建的ChildFrm.cpp
  • 所有相关的对话框类均使用标准的MFC AppWizard创建;
  • MaskHandle.cppMaskUnit.cpp – 由作者创建,用于蒙版图像处理;

GlobUse – 程序集,包含独立于主项目的过程,可根据需要包含在任何MFC项目中。

  • EasyAVI.cpp - 借用自 Andy Bantly 的文章“Easy AVI”;
  • MyRectTrack.cpp - 由作者为本项目创建,用于对Mask Recttrack进行灵活操作;
  • 其他代码由作者早期创建,并已用于其他项目,包括CodeProject

即使您是第一次使用MSVS,只需选择菜单Debug->Start without debugging,项目MyAviShop就应该开始构建并运行。

3. 代码解释

所有菜单和控件处理命令均使用标准的MFC AppWizard技术完成。因此,我认为没有什么比标准教程更能解释的了。我只介绍一些我自己的开发点。

3.1 蒙版可视化

包含在某个多边形区域内的蒙版可以使用两个图形上下文(黑白和某个缓冲区)进行划分。

//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);
}
  • 黑白上下文用白色填充;
  • 绘制被多边形包围的黑色区域;
  • 反转颜色:带黑色的白色多边形;
  • 将原始图像放入缓冲区上下文;
  • 使用SRCAND将黑白上下文中的黑白蒙版放在缓冲区内容上:在缓冲区上下文中,我们得到了被多边形包围的图像蒙版,背景为黑色。

3.2 蒙版 Recttrack

为了处理蒙版,插入了一些特殊类:

  • CMyRectTrack – 派生自Polygon_2D类;用于蒙版的移动、调整大小和旋转;
  • CMaskUnit - 派生自CObject类;用于存储蒙版信息:位置、大小、旋转角度、蒙版图像列表中的编号;
  • CMaskHandle - 派生自CObject类;用于管理CMaskUnit Objects列表,并同时引用目标图像列表和蒙版图像列表。

蒙版绘制过程如下:

//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. 使用此项目开发您自己的应用程序

您可以采用整个项目,将其重命名为我的前一篇CodeProject文章“MFC Project from Existing Code in One Click”的项目,并按您喜欢的方式组合和改进代码。

或者,您可以从本项目中选择GlobUse目录中的任何文件,并通过菜单Project->Existing Item将其包含到任何MFC项目中。

或者,您也可以简单地使用提供的演示中的MyAviShop.exe来“改进”任何AVI和/或网络场景捕获。

如果您引用我的代码,我将不胜感激。

讨论

本文的目的是,提供的项目可以为普通的 AVI 编辑程序提供良好的支持,甚至可以开发您自己的AVI Shop程序。

这展示了CodeProject在帮助开发者解决任何问题方面的性能。

结论、兴趣点和致谢

gif 插图是用MyAviShop本身创建的:一个会话执行操作,另一个会话“监视”执行过程。

本项目是用于实现您喜欢的一些技巧和效果的工具,请记住代码是开放的。

我早期版本的此作业的一些示例可在 YouTube/vl2525 上找到。

非常感谢 Andy Bantly 和 Darryl Bryk 的出色工作。

历史

  • 2019 年 4 月 2 日:初稿
© . All rights reserved.