⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avi2bmpdlg.cpp

📁 AVI视频分解成BMP图片以及BMP图片合成AVI视频
💻 CPP
字号:
// avi2bmpDlg.cpp : implementation file
//

#include "stdafx.h"
#include "avi2bmp.h"
#include "avi2bmpDlg.h"
#include "Vfw.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAvi2bmpDlg dialog

CAvi2bmpDlg::CAvi2bmpDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAvi2bmpDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAvi2bmpDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CAvi2bmpDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAvi2bmpDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAvi2bmpDlg, CDialog)
	//{{AFX_MSG_MAP(CAvi2bmpDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTNAVI2BMP, OnBtnavi2bmp)
	ON_BN_CLICKED(IDC_BTNSELECTAVI, OnBtnselectavi)
	ON_BN_CLICKED(IDC_SELECTBMPDIR, OnSelectbmpdir)
	ON_BN_CLICKED(IDC_BTNBMP2AVI, OnBtnbmp2avi)
	ON_BN_CLICKED(IDC_BTNCREATEAVI, OnBtncreateavi)
	ON_BN_CLICKED(IDC_GETBMPDIR, OnGetbmpdir)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAvi2bmpDlg message handlers

BOOL CAvi2bmpDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAvi2bmpDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAvi2bmpDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAvi2bmpDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}





void CAvi2bmpDlg::OnBtnavi2bmp() 
{
	// TODO: Add your control notification handler code here
	
	if (m_strAVIFileName.IsEmpty()||m_strBmpSeqPath.IsEmpty())
	{
      MessageBox("请输入AVI文件和bmp序列的位置","提示");
	  return;
	}
    AVItoBmp(m_strAVIFileName,m_strBmpSeqPath);
	MessageBox("完成!");
}

void CAvi2bmpDlg::OnBtnselectavi() 
{
	// TODO: Add your control notification handler code here
	static char BASED_CODE szFilter[] = "AVI(*.AVI)|*.AVI||";
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,this);
	if(dlg.DoModal()!=IDOK)return;
	m_strAVIFileName=dlg.GetPathName();
    SetDlgItemText(IDC_AVIFILEPATH,m_strAVIFileName);
}

void CAvi2bmpDlg::OnSelectbmpdir() 
{
	// TODO: Add your control notification handler code here
	BROWSEINFO  bi; //BROWSEINFO结构体   
    TCHAR   Buffer[MAX_PATH]="";
    TCHAR   FullPath[MAX_PATH]="";
	bi.hwndOwner=m_hWnd; //m_hWnd你的程序主窗口
	bi.pidlRoot=NULL;
	bi.pszDisplayName=Buffer;//返回选择的目录名的缓冲区
	bi.lpszTitle="请选择一个存放bmp序列的目录";   //弹出的窗口的文字提示
	bi.ulFlags=BIF_RETURNONLYFSDIRS | BIF_EDITBOX;//只返回目录。其他标志看MSDN
	bi.lpfn   =   NULL;   //回调函数,有时很有用                                             
	bi.lParam   =   0; 
    bi.iImage   =   0;
	ITEMIDLIST*   pidl   =   SHBrowseForFolder   (&bi);   //显示弹出窗口,ITEMIDLIST很重要
	if(SHGetPathFromIDList(pidl,FullPath))//在ITEMIDLIST中得到目录名的整个路径
	{
		SetDlgItemText(IDC_BMPSEQDIR,FullPath);
		m_strBmpSeqPath=FullPath;
	}
}
void CAvi2bmpDlg::OnBtnbmp2avi() 
{
	// TODO: Add your control notification handler code here
	if (m_strAVIFileName2.IsEmpty()||m_strBmpSeqPath2.IsEmpty())
	{
		MessageBox("请创建AVI文件和输入bmp序列的位置","提示");
	    return;
	}
	 BMPtoAVI(m_strAVIFileName2,m_strBmpSeqPath2);
     MessageBox("完成!");
}

void CAvi2bmpDlg::OnBtncreateavi() 
{
	// TODO: Add your control notification handler code here
	CFileDialog dlg(FALSE,"AVI文件(*.avi)|*.avi||",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"AVI文件(*.avi)|*.avi||",NULL);
    if(dlg.DoModal()==IDOK)
	{
		m_strAVIFileName2=dlg.GetPathName();
        SetDlgItemText(IDC_AVIFILEPATH2,m_strAVIFileName2);
		UpdateData(false);
	}
	
}

void CAvi2bmpDlg::OnGetbmpdir() 
{
	// TODO: Add your control notification handler code here
	BROWSEINFO  bi; //BROWSEINFO结构体   
    TCHAR   Buffer[MAX_PATH]="";
    TCHAR   FullPath[MAX_PATH]="";
	bi.hwndOwner=m_hWnd; //m_hWnd你的程序主窗口
	bi.pidlRoot=NULL;
	bi.pszDisplayName=Buffer;//返回选择的目录名的缓冲区
	bi.lpszTitle="请选择一个bmp序列的目录";   //弹出的窗口的文字提示
	bi.ulFlags=BIF_RETURNONLYFSDIRS | BIF_EDITBOX;//只返回目录。其他标志看MSDN
	bi.lpfn   =   NULL;   //回调函数,有时很有用                                             
	bi.lParam   =   0; 
    bi.iImage   =   0;
	ITEMIDLIST*   pidl   =   SHBrowseForFolder   (&bi);   //显示弹出窗口,ITEMIDLIST很重要
	if(SHGetPathFromIDList(pidl,FullPath))//在ITEMIDLIST中得到目录名的整个路径
	{
		SetDlgItemText(IDC_BMPSEQDIR2,FullPath);
		m_strBmpSeqPath2=FullPath;
	}
//	UpdateData();
}

void CAvi2bmpDlg::BMPtoAVI(CString szAviName, CString strBmpDir)
{
	CFileFind finder;
    strBmpDir += _T("\\*.*"); 
    AVIFileInit();
    AVISTREAMINFO strhdr;
    PAVIFILE pfile;
	PAVISTREAM ps; 
    int nFrames =0; 
    HRESULT hr; 
 
    BOOL bFind = finder.FindFile(strBmpDir);
    while(bFind)
    {
        bFind = finder.FindNextFile();
		if(!finder.IsDots() && !finder.IsDirectory())
        {
			CString str = finder.GetFilePath();
			FILE *fp = fopen(str,"rb");
			BITMAPFILEHEADER bmpFileHdr;
			BITMAPINFOHEADER bmpInfoHdr;
			fseek( fp,0,SEEK_SET);
			fread(&bmpFileHdr,sizeof(BITMAPFILEHEADER),1, fp);
			fread(&bmpInfoHdr,sizeof(BITMAPINFOHEADER),1, fp);
 
			BYTE *tmp_buf = NULL;
			if(nFrames ==0 )
			{
				AVIFileOpen(&pfile,szAviName,OF_WRITE | OF_CREATE,NULL);
				memset(&strhdr, 0, sizeof(strhdr));
				strhdr.fccType = streamtypeVIDEO;// stream type
				strhdr.fccHandler = 0;
				strhdr.dwScale = 1;
				strhdr.dwRate = 15;// 15 fps
				strhdr.dwSuggestedBufferSize = bmpInfoHdr.biSizeImage ;
				SetRect(&strhdr.rcFrame, 0, 0, bmpInfoHdr.biWidth, bmpInfoHdr.biHeight);
 
				// And create the stream;
				hr = AVIFileCreateStream(pfile,&ps,&strhdr);         
				// hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
			}
			tmp_buf = new BYTE[bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3];
			fread(tmp_buf, 1, bmpInfoHdr.biWidth * bmpInfoHdr.biHeight * 3, fp);
			hr = AVIStreamSetFormat(ps,nFrames,&bmpInfoHdr,sizeof(bmpInfoHdr));
			hr = AVIStreamWrite(ps,       // stream pointer
							nFrames ,     // time of this frame
                            1,          // number to write
                            (LPBYTE) tmp_buf,
                            bmpInfoHdr.biSizeImage , // size of this frame
                            AVIIF_KEYFRAME,                    // flags....
                            NULL,
                            NULL);
 
            nFrames ++; 
//////////////////////////////////////////////////////////////////////////
			//change the title
			CString cs;
		    cs.Format("正在合成第%5.5ld帧",long(nFrames));
	    	SetWindowText(cs);
		    cs.Format(m_strBmpSeqPath+"\\"+"Frame-%5.5ld.bmp",long(nFrames+1));
//////////////////////////////////////////////////////////////////////////
			fclose(fp);
 
		}
	}
 	AVIStreamClose(ps);
 	if(pfile != NULL)
	AVIFileRelease(pfile);
 	AVIFileExit();
}

void CAvi2bmpDlg::AVItoBmp(CString strAVIFileName, CString strBmpDir)
{

	AVIFileInit();
	PAVIFILE avi;
	int res=AVIFileOpen(&avi, strAVIFileName, OF_READ, NULL);
	int n = GetLastError();
	if (res!=AVIERR_OK)
	{
		//an error occures
		if (avi!=NULL)
			AVIFileRelease(avi);
		return ;
	}
	AVIFILEINFO avi_info;
	AVIFileInfo(avi, &avi_info, sizeof(AVIFILEINFO));
	PAVISTREAM pStream;
	res=AVIFileGetStream(avi, &pStream, streamtypeVIDEO /*video stream*/, 
	0 /*first stream*/);
	if (res!=AVIERR_OK)
	{
		if (pStream!=NULL)
			AVIStreamRelease(pStream);
		AVIFileExit();
		return ;
	}

	//do some task with the stream
	int iNumFrames;
	int iFirstFrame;
	iFirstFrame=AVIStreamStart(pStream);
	if (iFirstFrame==-1)
	{
		//Error getteing the frame inside the stream
		if (pStream!=NULL)
			AVIStreamRelease(pStream);
		AVIFileExit();
		return ;
	}
	iNumFrames=AVIStreamLength(pStream);
	if (iNumFrames==-1)
	{
		//Error getteing the number of frames inside the stream
		if (pStream!=NULL)
			AVIStreamRelease(pStream);
		AVIFileExit();
		return ;
	}

	//getting bitmap from frame
	BITMAPINFOHEADER bih;
	ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));

	bih.biBitCount=24; //24 bit per pixel
	bih.biClrImportant=0;
	bih.biClrUsed = 0;
	bih.biCompression = BI_RGB;
	bih.biPlanes = 1;
	bih.biSize = 40;
	bih.biXPelsPerMeter = 0;
	bih.biYPelsPerMeter = 0;
	//calculate total size of RGBQUAD scanlines (DWORD aligned)
	bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight ;

	PGETFRAME pFrame;
	pFrame=AVIStreamGetFrameOpen(pStream, NULL );

	AVISTREAMINFO streaminfo;
	AVIStreamInfo(pStream,&streaminfo,sizeof(AVISTREAMINFO));

	//Get the first frame
	BITMAPINFOHEADER bih2;
	long lsize = sizeof(bih2);
	int index=0;
	for (int i=iFirstFrame; i<iNumFrames; i++)
	{
		index= i-iFirstFrame;
		BYTE* pDIB = (BYTE*) AVIStreamGetFrame(pFrame, index); //
		AVIStreamReadFormat(pStream,index,&bih2,&lsize);
		BITMAPFILEHEADER stFileHdr;

		BYTE* Bits=new BYTE[bih2.biSizeImage];
		AVIStreamRead(pStream,index,1,Bits,bih2.biSizeImage,NULL,NULL);
		//RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih2.biSizeImage);

		bih2.biClrUsed =0;
		stFileHdr.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
		stFileHdr.bfSize=sizeof(BITMAPFILEHEADER);
		stFileHdr.bfType=0x4d42; 

		CString FileName;
		FileName.Format("Frame-%05d.bmp", index);
		CString strtemp = strBmpDir;
		strtemp += "\\";
		strtemp += FileName;
		FILE* fp=_tfopen(strtemp ,_T("wb"));

		CString cs;
		cs.Format("正在写第%5.5ld帧",long(i+1));
		SetWindowText(cs);
		cs.Format(m_strBmpSeqPath+"\\"+"Frame-%5.5ld.bmp",long(i));

		fwrite(&stFileHdr,1,sizeof(BITMAPFILEHEADER),fp);
		fwrite(&bih2,1,sizeof(BITMAPINFOHEADER),fp);
		int ff = fwrite(Bits,1,bih2.biSizeImage,fp);
		int e = GetLastError();
		fclose(fp);
		/////
		delete Bits;
		//CreateFromPackedDIBPointer(pDIB, index);
	}
	AVIStreamGetFrameClose(pFrame);
	//close the stream after finishing the task
	if (pStream!=NULL)
	AVIStreamRelease(pStream);
	AVIFileExit();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -