利用vfw库将一系列bmp图转换为压缩的avi视频

#include "stdafx.h"
#include "Vfw.h"

#pragma comment( lib, "Vfw32.lib" )
#pragma warning ( disable : 4996 )

//======================================================================================
//
// 功能 : 将目录中的图像件制用成AVI视频
// 参数 : videoWidth、videoHeight代表输出的视频的宽度和高度
//        pAviName 代表输出的视频的文件名
//		  pDir代表存放图像文件的路径. 此文件夹下的图像文件的尺寸需要一致
//		  bpp 代表图像中每像素位数
//======================================================================================
void ImageToAVI( LPCTSTR pAviName, LPCTSTR pDir, int videoWidth, int videoHeight, int bpp )
{
	if ( NULL == pAviName || NULL == pDir )
		return;

	// 初始化AVI 库
	AVIFileInit();

	//
	// Create AVI file
	//
	PAVIFILE pAviFile = NULL;
	HRESULT hr = AVIFileOpen( &pAviFile, pAviName, OF_WRITE | OF_CREATE, NULL );
	if ( 0 != hr )
	{
		ASSERT( FALSE );
		return;
	}

	//
	// Create AVI video stream
	//
	AVISTREAMINFO strhdr;
	memset( &strhdr, 0, sizeof( strhdr ) );

	strhdr.fccType = streamtypeVIDEO;
	strhdr.fccHandler = mmioFOURCC('X','V','I','D');
	strhdr.dwScale = 1;
	strhdr.dwRate = 25;//设置帧速

	// Calc image size
	UINT pitch = ( videoWidth * bpp + 31 ) / 32 * 4;
	UINT biSizeImage = ( videoWidth * bpp + 31 ) / 32 * 4 * videoHeight;
	strhdr.dwSuggestedBufferSize = biSizeImage;

	SetRect( &strhdr.rcFrame, 0, 0, videoWidth, videoHeight );

	// And create the stream;
	PAVISTREAM pAviStream = NULL;
	hr = AVIFileCreateStream( pAviFile, &pAviStream, &strhdr );
	if ( 0 != hr )
	{
		ASSERT( FALSE );

		AVIFileRelease( pAviFile );
		pAviFile = NULL;

		return;
	}

	//
	//设置压缩选项,创建压缩流
	//
	AVICOMPRESSOPTIONS  options; 
	AVICOMPRESSOPTIONS * aoptions[1] = {&options};
	memset(&options,0,sizeof(options));
	options.fccType = ICTYPE_VIDEO ;
	options.fccHandler = mmioFOURCC('X','V','I','D');
	options.dwQuality = 2000;
	options.dwFlags = 8 ;
	options.lpParms = 0;
	options.cbParms = 0 ;
	PAVISTREAM pCompressedStream;
	AVIMakeCompressedStream(&pCompressedStream,pAviStream,&options,NULL);
	
	//
	// Set stream format
	//
	BITMAPINFOHEADER bih;
	memset( &bih, 0, sizeof( BITMAPINFOHEADER ) );

	bih.biBitCount = bpp;
	bih.biClrImportant = 0;
	bih.biClrUsed = 0;
	bih.biCompression = BI_RGB;
	bih.biPlanes = 1;
	bih.biSize = 40;
	bih.biXPelsPerMeter = 0;
	bih.biYPelsPerMeter = 0;
	bih.biWidth = videoWidth;
    bih.biHeight = videoHeight;
    bih.biSizeImage = biSizeImage;

	hr = AVIStreamSetFormat( pCompressedStream, 0, &bih, sizeof( bih ) );

	if ( 0 != hr )
	{
		ASSERT( FALSE );

		AVIStreamClose( pAviStream );
		pAviStream = NULL;

		AVIFileRelease( pAviFile );
		pAviFile = NULL;
	}

	//
	// 遍历每一个图像,制作成视频中的一帧帧图像
	//
	TCHAR imageDir[ MAX_PATH ];
	memset( imageDir, 0, sizeof( imageDir ) );
	sprintf( imageDir, "%s\\*.*", pDir );

	CFileFind finder;
	BOOL bFind = finder.FindFile( imageDir );
	int nFrames =0;

	// 图像数据缓冲区
	BYTE * pData = new BYTE[ biSizeImage ];
	if ( pData )
	{
		memset( pData, 0, biSizeImage );
	}
	
	while ( bFind )
	{
		bFind = finder.FindNextFile();
	
		if ( !finder.IsDots() && !finder.IsDirectory() )
		{
			// 获取图像文件绝对路径
			CString str = finder.GetFilePath();

			//
			// Open Image and get image info & data
			//
			CImage img;
			if ( FAILED( img.Load( str ) ) )
			{
				TRACE( "Warning : fail to load file %s!!!\n", str );
				continue;
			}

			//
			// 读取图像数据,更新AVI视频帧
			//
			if ( pData )
			{
				int w = min( videoWidth, img.GetWidth() );
				int h = min( videoHeight, img.GetHeight() );

				for ( int i = 0; i < h; i++ )
				for ( int j = 0; j < w; j++ )
				{
					COLORREF clr = img.GetPixel( j, h-1-i);//(j,i)
					
					pData[ i * pitch + j * ( bpp / 8 ) + 0 ] = GetBValue( clr );
					pData[ i * pitch + j * ( bpp / 8 ) + 1 ] = GetGValue( clr );
					pData[ i * pitch + j * ( bpp / 8 ) + 2 ] = GetRValue( clr );
				}

				hr = AVIStreamWrite( pCompressedStream, nFrames, 1, pData, biSizeImage, AVIIF_KEYFRAME, NULL, NULL );
				ASSERT( 0 == hr );
			}

			nFrames ++;
		}
	}

	if (pData!=NULL)
	{
		delete [] pData;
		pData = NULL;
	}

	if (pAviStream!=NULL)
	{
		AVIStreamClose(pAviStream);
		pAviStream = NULL;
	}

	if (pCompressedStream!=NULL)
	{
		AVIStreamClose(pCompressedStream);
		pCompressedStream = NULL;
	}

	if (pAviFile!=NULL)
	{
		AVIFileRelease(pAviFile);
		pAviFile = NULL;
	}

	AVIFileExit();

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值