| 
		
			| 
	
	
		
			
		
				
						
								| 利用Visual C++实现AVI文件的图像截取 |  
								| 
 |  
								| 2001-10-22· 
              ·刘 涛 ··yesky 
 
 |  
								| AVI文件就是我们所说的多媒体文件,所谓的AVI图像就是视频图像,该文件是一个RIFF说明文件,它用于获取、编辑、演示音频、视频序列。一般的AVI文件包含音频流和视频流,有的特殊的AVI还包含一个控制路径或MIDI路径作为附加的数据流。
 
 现在播放AVI文件的软件很多,但大多无法从AVI视频文件中读取一帧图像并生成BMP格式的文件。笔者在使用AVI文件开发项目过程中对AVI文件的
操作积累了一些经验,对于如何实现从AVI视频流中获取任意帧的图像数据并存储成BMP文件,其中最关键的是要从AVI文件中获取具体某一帧的图像数据,
为此我利用Windows提供的API函数实现了自定义的CAvi类,用于操作AVI文件。
 
 在使用API函数操作AVI文件时,一定
要注意用AVIFileInit()来初始化AVI库,程序结束时用AVIFileExit()释放AVI库,否则API函数无法使用。现以操作包含真彩
色图像的AVI文件为例,给出Cavi类的部分函数的具体实现,其中CaviCreate()函数用于读取AVI文件信息并初始化Cavi类的成员,例如
根据AVI文件信息定义每帧图像的宽、高、每帧图像的信息头结构等等;函数AviRead(int
mFrame)用于从AVI文件中读取第mFrame帧。实现代码显示如下:
 
 
 | //Cavi类头文件定义; class CAvi file://AVI类,处理AVI文件
 {
 public:
 int cy;//图象高
 int cx;//图象宽
 file://long m_maxFrame;
 BYTE *pData;//寸储图象数据
 BITMAPINFO *m_pBMI;//位图文件信息头
 PAVISTREAM pavi;//AVI流
 PAVIFILE pfile;//AVI文件指针
 AVIFILEINFO * pfi; file://AVI信息
 BOOL AviRead(int mFrame);//读AVI文件的第mFrame帧
 CAvi();//标准构造函数
 CAviCreate(CString &string);//用文件名初始化AVI类的成员
 virtual ~CAvi();
 };
 //Cavi类文件实现部分;
 CAvi::CAvi()
 { AVIFileInit();//初始化AVI库
 cx=0;//定义图象宽、高、等成员
 cy=0;
 m_pBMI=NULL;
 pData=NULL;
 file://m_maxFrame=0;
 pfi=NULL;
 }
 CAvi::~CAvi()//析构、释放指针
 {
 // AVIFileClose(pfile);
 AVIFileExit();
 if(pData!=NULL)
 delete pData;
 pData=NULL;
 
 if(m_pBMI!=NULL)
 delete m_pBMI;
 m_pBMI=NULL;
 if(pfi!=NULL)
 delete pfi;
 pfi=NULL;
 }
 CAvi::CAviCreate(CString &string)//读文件初始化该类
 {
 HRESULT hr;
 pfi=new AVIFILEINFO;
 hr = AVIFileOpen(&pfile, // returned file pointer
 string, // file name
 OF_READ, // mode to open file with
 NULL);
 hr= AVIFileInfo(pfile, file://获取AVI信息,放入pfi中
 pfi,
 sizeof(AVIFILEINFO)
 );
 cx=pfi->dwWidth;//图象宽、高
 cy=pfi->dwHeight;
 hr=AVIFileGetStream(//将AVI变成视频流
 pfile,
 &pavi,
 streamtypeVIDEO,
 0//LONG lParam
 );
 m_pBMI=new BITMAPINFO;//定义BMP信息头
 m_pBMI->bmiHeader.biBitCount=24;
 m_pBMI->bmiHeader.biClrImportant=0;
 m_pBMI->bmiHeader.biClrUsed=0;
 m_pBMI->bmiHeader.biCompression=BI_RGB;
 m_pBMI->bmiHeader.biHeight=cy;
 m_pBMI->bmiHeader.biWidth=cx;
 m_pBMI->bmiHeader.biPlanes=1;
 m_pBMI->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
 m_pBMI->bmiHeader.biXPelsPerMeter=0;
 m_pBMI->bmiHeader.biYPelsPerMeter=0;
 m_pBMI->bmiHeader.biSizeImage=cx*cy*3;
 pData=(BYTE*)new char[cx*cy*3];//根据AVI中BMP图象的信息定义缓冲区
 }
 BOOL CAvi::AviRead(int mFrame)//将AVI文件的M帧数据读入PData缓冲区
 {
 HRESULT hr;
 hr= AVIStreamRead( pavi,
 mFrame,
 1,
 pData,
 cx*cy*3,
 NULL,
 NULL
 );
 if(hr==0)
 return TRUE;
 else
 return FALSE;
 }
 
 | 
 
 上述Cavi类实现部分所涉及到的API函数可以参考微软提供的MSDN。Cavi类中的pData缓冲区存放AVI文件中的具体某一帧图像数据,同时
Cavi类的m_pBMI为BMP图像文件信息结构,这时可以根据图像的大小定义BMP图像文件头结构,关于BMP文件的存储,由于篇幅的原因,我不在多
讲了,有兴趣的读者可以参见笔者的拙作"Visual
C++6.0开发灰度位图处理"(天极网软件栏目2001.9.10发表),该文里面讲述了如何存取BMP文件。以上程序在Windows2000、
Visual C++6.0环境下顺利编译通过,运行正常。
 |      
	    
    
 |  | 
		
			| 
			
				| 
	|  |  | 日 | 一 | 二 | 三 | 四 | 五 | 六 | 
|---|
 | 28 | 29 | 30 | 1 | 2 | 3 | 4 |  | 5 | 6 | 7 | 8 | 9 | 10 | 11 |  | 12 | 13 | 14 | 15 | 16 | 17 | 18 |  | 19 | 20 | 21 | 22 | 23 | 24 | 25 |  | 26 | 27 | 28 | 29 | 30 | 31 | 1 |  | 2 | 3 | 4 | 5 | 6 | 7 | 8 |  |  常用链接留言簿(7)随笔档案文章分类文章档案相册收藏夹c++搜索最新评论
	阅读排行榜评论排行榜
 |  |