1.mfc中实现如何写入数据到配置文件(txt文本)
将下拉框中显示的内容(设置为CString类型)因为主界面需要用到这些数据,于是我将需要发送交互的变量,都放在全局变量文件中(Global.h/Global.cpp)
同时我使用了相对路径,将文本信息放在如下执行程序目录下,方便用户查询找到,同时为了标记保存配置文件信息不同,用时间戳作为文件名
//保存配置文件按钮
void InputMenu::OnBnClickedSaveconfig()
{
// TODO: 在此添加控件通知处理程序代码
//char * pszFileName = "F:\\test.txt";//指定路径
//MFC获取程序目录相对路径,小心文件是放在项目外面的x64-Debug里面 自己写的
CString pszFileName;
GetModuleFileName(NULL, pszFileName.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);
pszFileName.ReleaseBuffer();
int pos = pszFileName.ReverseFind('\\');
pszFileName = pszFileName.Left(pos);
//获取时间戳
CTime currTime;
currTime = CTime::GetCurrentTime();
//CString strTime_Saveconfig;
strTime_Saveconfig.Format(_T("%.4d-%.2d-%.2d-%.2d-%.2d-%.2d"), currTime.GetYear(), currTime.GetMonth(), currTime.GetDay(), currTime.GetHour(), currTime.GetMinute(), currTime.GetSecond());
pszFileName = pszFileName + "\\" + strTime_Saveconfig + _T(".txt");
CStdioFile file;
CFileException fileException;
CString strline;
BOOL flag = file.Open(pszFileName, CFile::modeCreate | CFile::typeText | CFile::modeReadWrite);
//CFile::typeText:以文本文件的形式打开文件
//CFile::modeWrite:以只写方式打开文件
//strFolderPath//文档保存路径 strFolderPath_Picture截图保存路径 strFolderPath_Video截取视频保存路径 PictureCutformat截图保存格式
if (flag && strFolderPath != ""&&strFolderPath_Picture != ""&&strFolderPath_Video != ""&&PictureCutformat != "")
{
file.SeekToEnd();
// "文档保存路径:" 截图保存路径: 截取视频保存路径: 截图保存格式: 头文件解析: 长宽: 帧频: 比特位:
strline = strFolderPath + "," + strFolderPath_Picture + "," + strFolderPath_Video +
"," + PictureCutformat + "," + ComboInput1_flg + "," + ComboInput2_flg
+ "," + ComboInput3_flg + "," + ComboInput4_flg;
file.WriteString(strline);
MessageBox("成功添加至文档末尾");
SetDlgItemText(IDC_ConfigSaveTxt, strTime_Saveconfig);
UpdateData(FALSE);
file.SeekToBegin();
file.Close();
}
else
{
MessageBox("添加失败,不能添加空字符,请重新配置");
}
}
2.完成mfc读取文本文档数据到下拉框,编辑框中
参考以前积累,采用先读取文本文本,然后调用切割字符函数,在读取mfc中
同时需要注意,主界面与子界面同时运用到了切割字符函数,故将其作为全局函数
//声明文本信息的字符分割函数
int SplitString(LPCTSTR lpszStr, LPCTSTR lpszSplit, CStringArray& rArrString, BOOL bAllowNullString);
//分割文本信息的字符函数
int SplitString(LPCTSTR lpszStr, LPCTSTR lpszSplit, CStringArray& rArrString, BOOL bAllowNullString)
{
rArrString.RemoveAll();
CString szStr = lpszStr;
szStr.TrimLeft();
szStr.TrimRight();
if (szStr.GetLength() == 0)
{
return 0;
}
CString szSplit = lpszSplit;
if (szSplit.GetLength() == 0)
{
rArrString.Add(szStr);
return 1;
}
CString s;
int n;
do {
n = szStr.Find(szSplit);
if (n > 0)
{
rArrString.Add(szStr.Left(n));
szStr = szStr.Right(szStr.GetLength() - n - szSplit.GetLength());
szStr.TrimLeft();
}
else if (n == 0)
{
if (bAllowNullString)
rArrString.Add(_T(""));
szStr = szStr.Right(szStr.GetLength() - szSplit.GetLength());
szStr.TrimLeft();
}
else
{
if ((szStr.GetLength()>0) || bAllowNullString)
rArrString.Add(szStr);
break;
}
} while (1);
return (int)rArrString.GetSize();
}
同时在“读取配置”按钮,写如下的响应函数:
注意在后面为了能够将读取的信息显示到相应的控件,采用了全局变量
//下拉框的索引值
int ComboInput1_index = 0;//0 1 2
int ComboInput2_index = 0;//0 1 2
int ComboInput3_index = 0;//0 1 2
int ComboInput4_index = 0;//0 1 2
int m_PictureCut_index = 0;// 0 1
同时在子界面的初始化函数中,进行添加如下函数,保证子界面中控件能实时更新文本信息
做类似操作:因为下拉框了解采用SetCurSel,故采用这种笨方法
//设置默认选项
//m_cbx1.SetCurSel(0);
//int ComboInput1_index = 0;
m_cbx1.SetCurSel(ComboInput1_index);//更新下拉框显示
UpdateData(FALSE);
//通过读取txt,重新配置
//"文档保存位置"下的编辑框,能实时更新路径信息,并且不丢失上次使用痕迹
SetDlgItemText(IDC_FileNameEdit, strFolderPath);
UpdateData(FALSE);
同时在响应函数中,也做了实时更新操作:有点繁琐,但是为了彼此不相互干扰,也只能先想这么做,有好方法的朋友,可以告知
//读取设置好的配置文件
void InputMenu::OnBnClickedReadconfig()
{
// TODO: 在此添加控件通知处理程序代码
//CString strFileName = _T("F:\\abc.txt");//指定路径
//选择任一路径
CString strFileName;
CStdioFile file;
CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("txt记事本(*.txt)|*.txt|ini文档(*.ini)|*.ini|pem文档(*.pem)|*.pem||"), AfxGetMainWnd());
if (IDOK == dlg.DoModal())
{
strFileName = dlg.GetPathName();
//SetDlgItemText(IDC_ConfigSaveTxt, strFileName);//显示打开要读取配置文件位置
if (!PathFileExists(strFileName))
{
MessageBox("打开文件错误");
}
if (!file.Open(strFileName, CFile::modeRead))
{
MessageBox("打开文件错误");
}
//vector<CString> vecResult;
CString strValue = _T("");
CString szSplit = _T(",");
CStringArray szList;
while (file.ReadString(strValue))
{
//字符分割函数
int Count = SplitString(strValue, szSplit, szList, FALSE);
if (0 == Count)
{
MessageBox(TEXT("err"));
}
//读取文本字符中原来数据,进行重置
strFolderPath = szList.GetAt(0);
strFolderPath_Picture = szList.GetAt(1);
strFolderPath_Video = szList.GetAt(2);
PictureCutformat = szList.GetAt(3);
ComboInput1_flg = szList.GetAt(4);
ComboInput2_flg = szList.GetAt(5);
ComboInput3_flg = szList.GetAt(6);
ComboInput4_flg = szList.GetAt(7);
//四个下拉框文本信息的更新
//第一个下拉框显示
if (ComboInput1_flg == "类一")
{
ComboInput1_index = 0;
m_cbx1.SetCurSel(ComboInput1_index);
UpdateData(FALSE);
}
else if (ComboInput1_flg == "类二")
{
ComboInput1_index = 1;
m_cbx1.SetCurSel(ComboInput1_index);
UpdateData(FALSE);
}
else if (ComboInput1_flg == "类三")
{
ComboInput1_index = 2;
m_cbx1.SetCurSel(ComboInput1_index);
UpdateData(FALSE);
}
//第二个下拉框
if (ComboInput2_flg == "类一")
{
ComboInput2_index = 0;
m_cbx2.SetCurSel(ComboInput2_index);
UpdateData(FALSE);
}
else if (ComboInput2_flg == "类二")
{
ComboInput2_index = 1;
m_cbx2.SetCurSel(ComboInput2_index);
UpdateData(FALSE);
}
else if (ComboInput2_flg == "类三")
{
ComboInput2_index = 2;
m_cbx2.SetCurSel(ComboInput2_index);
UpdateData(FALSE);
}
//第三个下拉框
if (ComboInput3_flg == "类一")
{
ComboInput3_index = 0;
m_cbx3.SetCurSel(ComboInput3_index);
UpdateData(FALSE);
}
else if (ComboInput3_flg == "类二")
{
ComboInput3_index = 1;
m_cbx3.SetCurSel(ComboInput3_index);
UpdateData(FALSE);
}
else if (ComboInput3_flg == "类三")
{
ComboInput3_index = 2;
m_cbx3.SetCurSel(ComboInput3_index);
UpdateData(FALSE);
}
//第四个下拉框
if (ComboInput4_flg == "类一")
{
ComboInput4_index = 0;
m_cbx4.SetCurSel(ComboInput4_index);
UpdateData(FALSE);
}
else if (ComboInput4_flg == "类二")
{
ComboInput4_index = 1;
m_cbx4.SetCurSel(ComboInput4_index);
UpdateData(FALSE);
}
else if (ComboInput4_flg == "类三")
{
ComboInput4_index = 2;
m_cbx4.SetCurSel(ComboInput4_index);
UpdateData(FALSE);
}
//第五个下拉框-图片格式下拉框
if ( PictureCutformat == "png")
{
m_PictureCut_index = 0;
m_PictureCut.SetCurSel(m_PictureCut_index);
UpdateData(FALSE);
}
else if (PictureCutformat == "jpg")
{
m_PictureCut_index = 1;
m_PictureCut.SetCurSel(m_PictureCut_index);
UpdateData(FALSE);
}
//通过读取txt,重新配置
//"文档保存位置"下的编辑框,能实时更新路径信息,并且不丢失上次使用痕迹
SetDlgItemText(IDC_FileNameEdit, strFolderPath);
UpdateData(FALSE);
//"截图保存位置"下的编辑框,能实时更新路径信息,并且不丢失上次使用痕迹
SetDlgItemText(IDC_FileName_Picture, strFolderPath_Picture);
UpdateData(FALSE);
//"截取视频保存位置"下的编辑框,能实时更新路径信息,并且不丢失上次使用痕迹
SetDlgItemText(IDC_FileName_VideoCut, strFolderPath_Video);
UpdateData(FALSE);
}
file.Close();
}
}
3.实现点击“开始录制”按钮,从开始播放位置,不断截视频图片,然后点击“结束录制”,开始将在录制过程中所截图的一段图片,转成视频aviopencv保存视频
int imag_index = 0;//视频中截取的图片数目
//需要获得源视频文件的编码方式
int fps = (int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FPS); //帧率
CvSize size = cvSize(
(int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty(pCapture, CV_CAP_PROP_FRAME_HEIGHT));
while (pFrame)
{
WaitForSingleObject(start_event, INFINITE);
start_event.SetEvent();
if (terminate_flg == -1)
{
terminate_flg = 0;
_endthreadex(0);
};
pThis->Display(pFrame, IDC_VIDEO);
Sleep(33);
//截取图片
if (1 == videoCut_flg)
{
char image_name[13];
sprintf_s(image_name, "%s%d%s", "image", ++imag_index, ".jpg");//保存的图片名
cvSaveImage(image_name, pFrame); //保存一帧图片
}
else if (2 == videoCut_flg)//截取图片转视频
{
int i = 0;
IplImage* img = 0;
char image_name[13];
printf("------------- image to video ... ----------------\n");
//初始化视频编写器,参数根据实际视频文件修改
CvVideoWriter *writer = 0;
int isColor = 1;
writer = cvCreateVideoWriter(strFolderPath_Video_Save, CV_FOURCC('X', 'V', 'I', 'D'), fps, size, isColor);
while (i < imag_index)
{
sprintf_s(image_name, "%s%d%s", "image", ++i, ".jpg");
img = cvLoadImage(image_name);
if (!img)
{
printf("Could not load image file...\n");
exit(0);
}
cvWriteFrame(writer, img);
char c = cvWaitKey(33);//延时,每秒钟约33帧;符合人眼观看速度;
if (c == 27) break;
}
cvReleaseImage(&img);
cvReleaseVideoWriter(&writer);
videoCut_flg = 0;//归零
imag_index = 0;//这个也要置零 否则其他的照片会影响视频
AfxMessageBox(_T("截取视频成功!"));
}
pFrame = cvQueryFrame(pCapture );
}
参照:如下的源代码,写出:
// 该程序实现视频和图片的相互转换.
// Image_to_video()函数将一组图片合成AVI视频文件.
// Video_to_image()函数将AVI视频文件读入,将每一帧存储为jpg文件.
//
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#define NUM_FRAME 300 //只处理前300帧,根据视频帧数可修改
void Video_to_image(char* filename)
{
printf("------------- video to image ... ----------------\n");
//初始化一个视频文件捕捉器
CvCapture* capture = cvCaptureFromAVI(filename);
//获取视频信息
cvQueryFrame(capture);
int frameH = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
int numFrames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
printf("\tvideo height : %d\n\tvideo width : %d\n\tfps : %d\n\tframe numbers : %d\n", frameH, frameW, fps, numFrames);
//定义和初始化变量
int i = 0;
IplImage* img = 0;
char image_name[13];
//cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
//读取和显示
while (1)
{
img = cvQueryFrame(capture); //获取一帧图片
//cvShowImage("mainWin", img); //将其显示
char key = cvWaitKey(20);
sprintf(image_name, "%s%d%s", "image", ++i, ".jpg");//保存的图片名
cvSaveImage(image_name, img); //保存一帧图片
if (i == NUM_FRAME) break;
}
cvReleaseCapture(&capture);
//cvDestroyWindow("mainWin");
}
//char filename[13] = "text1.mp4";
//CvCapture* capture = cvCaptureFromAVI(filename);
//int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); //帧率
//CvSize size = cvSize(
// (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
// (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
//
//void Image_to_video()
//{
// int i = 0;
// IplImage* img = 0;
// char image_name[13];
// printf("------------- image to video ... ----------------\n");
// //初始化视频编写器,参数根据实际视频文件修改
// CvVideoWriter *writer = 0;
// int isColor = 1;
// //int fps = 30; // or 25
// //int frameW = 400; // 744 for firewire cameras
// //int frameH = 240; // 480 for firewire cameras
// writer = cvCreateVideoWriter("out3.avi", CV_FOURCC('X', 'V', 'I', 'D'), fps, size, isColor);
//
// //创建窗口
// //cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
// while (i<NUM_FRAME)
// {
// sprintf(image_name, "%s%d%s", "image", ++i, ".jpg");
// img = cvLoadImage(image_name);
// if (!img)
// {
// printf("Could not load image file...\n");
// exit(0);
// }
// //cvShowImage("mainWin", img);
// //char key = cvWaitKey(20);
// cvWriteFrame(writer, img);
// char c = cvWaitKey(33);//延时,每秒钟约33帧;符合人眼观看速度;
// if (c == 27) break;
// }
// cvReleaseImage(&img);
// cvReleaseVideoWriter(&writer);
// //cvDestroyWindow("mainWin");
//}
int main(int argc, char *argv[])
{
char filename[13] = "out3.avi";
Video_to_image(filename); //视频转图片
//Image_to_video(); //图片转视频
return 0;
}
//--------------------------------------------------------------------------------