以前写过打开AVI视频文件的程序,不过那时候在获取一帧的时候使用的是while(1)死循环,每次退出都会卡死,而且不能暂停。
使用while(1)源代码:
void CReadVideoDlg::OnFileOpen()
{
// TODO: Add your control notification handler code here
// 文件打开对话框
CFileDialog dlg(true,"*.avi",NULL,NULL,"*.avi|*.avi||");
if (dlg.DoModal()==IDOK)
{
strAviFilePath = dlg.GetPathName();
}else
{
return;
}
}
void CReadVideoDlg::OnVideoPro()
{
// TODO: Add your control notification handler code here
//声明IplImage指针
IplImage* pImage = NULL;
CvCapture* pCapture = NULL;
//打开AVI视频文件
if(strAviFilePath=="") //判断文件路径是否为空
{
MessageBox("请先选择AVI视频文件!");
return;
}else
{
if(!(pCapture = cvCaptureFromFile(strAviFilePath)))
{
MessageBox("打开AVI视频文件失败!");
return;
}
}
//逐帧读取视频
while(pImage = cvQueryFrame( pCapture ))
{
CDC *pDC1 = GetDlgItem(IDC_PICTUREBOX1)->GetDC();//根据ID获得窗口指针再获取与该窗口关联的上下文指针
HDC hdc1= pDC1->GetSafeHdc(); // 获取设备上下文句柄
CRect rect1; // 矩形类
GetDlgItem(IDC_PICTUREBOX1)->GetClientRect(&rect1); // 获取box1客户区
CvvImage cimg1; //
cimg1.CopyOf(pImage);
cimg1.DrawToHDC(hdc1,&rect1); //输出图像
ReleaseDC( pDC1 );
cimg1.Destroy(); //销毁
if( cvWaitKey(50) >= 0 ) break;
}
cvReleaseCapture(&pCapture);
}
今天使用的是定时器来播放AVI文件:
void CMyDlg::Onopenfile() ///打开文件
{
// TODO: Add your control notification handler code here
// 文件打开对话框
CFileDialog dlg(true,"*.avi",NULL,NULL,"*.avi|*.avi||");
if (dlg.DoModal()==IDOK)
{
strAviFilePath = dlg.GetPathName();
}
else
{
return;
}
//打开AVI视频文件
if(strAviFilePath=="") //判断文件路径是否为空
{
MessageBox("请先选择AVI视频文件!");
return;
}
else
{
if(!(pCapture = cvCaptureFromFile(strAviFilePath)))
{
MessageBox("打开AVI视频文件失败!");
return;
}
}
isplay=false;
}
void CMyDlg::Onplay() //播放
{
// TODO: Add your control notification handler code here
SetTimer(1,40,NULL); //每隔一段时间读出一帧视频图像
isplay=true;
}
void CMyDlg::Onstop() //暂停
{
// TODO: Add your control notification handler code here
if(isplay==true)
{
KillTimer(1);
}
}
void CMyDlg::OnOK() //退出
{
// TODO: Add extra validation here
if(isplay==true)
{
KillTimer(1);
}
cvReleaseCapture(&pCapture);
CDialog::OnOK();
}
void CMyDlg::OnTimer(UINT nIDEvent) //定时响应函数
{
// TODO: Add your message handler code here and/or call default
pImage = cvQueryFrame( pCapture ); //抓取一帧
//显示到窗口
CDC *pDC1 = GetDlgItem(IDC_PICTUREBOX1)->GetDC();//根据ID获得窗口指针再获取与该窗口关联的上下文指针
HDC hdc1= pDC1->GetSafeHdc(); // 获取设备上下文句柄
CRect rect1; // 矩形类
GetDlgItem(IDC_PICTUREBOX1)->GetClientRect(&rect1); // 获取box1客户区
CvvImage cimg1; //
cimg1.CopyOf(pImage);
cimg1.DrawToHDC(hdc1,&rect1); //输出图像
ReleaseDC( pDC1 );
cimg1.Destroy(); //销毁
CDialog::OnTimer(nIDEvent);
}
使用定时器播放可以通过设置SetTimer(1,40,NULL); 中的第二个参数来改变播放速率。40单位是微秒