📄 avi2bmpdlg.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 + -