#include "CSTLDlg.h"
川哥做到这个界面上有单张处理跟批处理两个按钮,其中读文件都是一样的,一次只打开一张,只不过批处理是把整个文件夹下的图片都处理了一遍。下面先说单张处理:
void CInpaintDlg::OnBnClickedSingleProcess()
{
/*
当定义UNICODE时,TCHAR就是wchar_t
#ifdef UNICODE typedef wchar_t TCHAR;
#else typedef unsigned char TCHAR;
#endif
*/
std::valarray<TCHAR> folder_path(path_name_.GetBuffer(),
path_name_.GetLength() + 1);
std::valarray<TCHAR> file_name(folder_path);
PathRemoveFileSpec(&folder_path[0]); //Removes the trailing file name and backslash from a path, if they are present.
PathStripPath(&file_name[0]); //Removes the path portion of a fully qualified path and file
std::vector<std::string> files;
files.push_back(CT2CA(&file_name[0]).m_psz); //Adds an element to the end of the string
ReleaseInpainter();
inpainter_ = new Inpainter;
inpainter_->InpaintWizard(CT2CA(path_name_).m_psz);
inpainter_->ResetCounters();
inpainter_->BatchInpaint(CT2CA(&folder_path[0]).m_psz, files);
MessageBox(_T("单张处理完成!"));
}
而多张图片的处理是这样的
void CInpaintDlg::OnBnClickedBatchProcess()
{
std::valarray<TCHAR> folder_path(path_name_.GetBuffer(),
path_name_.GetLength() + 1);
PathRemoveFileSpec(&folder_path[0]);
CString search_mask;
search_mask.Format(_T("%s\\*.*"), &folder_path[0]); //很灵活的CString处理方式!
std::vector<std::string> files;
WIN32_FIND_DATA find_data;
HANDLE find_handle = FindFirstFile(search_mask, &find_data);
if (INVALID_HANDLE_VALUE == find_handle)
return;
files.push_back((const char *)CT2CA(find_data.cFileName));
while (FindNextFile(find_handle, &find_data))
files.push_back((const char *)CT2CA(find_data.cFileName));
FindClose(find_handle);
//至此找寻文件操作完成
if (files.empty())
throw "find file failed.";
if (!inpainter_)
inpainter_ = new Inpainter;
inpainter_->InpaintWizard(CT2CA(path_name_).m_psz);
if (IDYES != MessageBox(_T("开始批处理?"), 0, MB_YESNO))
return;
inpainter_->ResetCounters();
inpainter_->BatchInpaint(CT2CA(&folder_path[0]).m_psz, files);
CString batch_process_message;
batch_process_message.Format(
_T("批处理完成!\n共处理图片:%d张\n处理时间:%d秒"),
inpainter_->number_of_inpainted(),
inpainter_->number_of_time());
MessageBox(batch_process_message);
}
其中这两个函数将文件名传递的源头BatchInpaint(CT2CA(&folder_path[0]).m_psz, files)里面是进行字符串处理的……这里先不贴了。
其中会发现有两种应用了STL(Standard Template Lib)的数据类型,(关于STL的类型问题,推荐这篇PKU的猛将兄翻译的东西,三十分钟掌握STL)分别为:
std::valarray<TCHAR> folder_path
std::vector<std::string> files
最初不了解STL,被这几个狰狞的数据类型吓坏了,现在也是一知半解吧,希望各位牛人能够推荐几篇针对字符串容器的教程撒。但是明白用操作字符或者字符串类似的方法,可以将这些货转化成亲切的char*,我的做法如下:
std::vector<std::string> &file_names的操作如下:
strcpy(pic_path, (inpainted_path + "\\" + file_names[i]).c_str());
std::valarray<TCHAR> folder_path的操作如下:
for(int i=0; folder_path[i]!='\0'; i++)
{
s_log<<(char)folder_path[i];
}
按照自己的看法,这几个货就是一个指针,指针的类型和尖括号里面的数据类型一致,valarray和vector都不是STL中特别复杂的结构容器,因此不必特别在意他们。
附录:valarray与vector各自的操作
Vector对象最重要的几种操作
1. v.size() 当前使用数据的大小
2. v.empty() 判断vector是否为空
3. v[n] 返回v中位置为n的元素
4. v1=v2 把v1的元素替换为v2元素的副本
5. v1= =v2 判断v1与v2是否相等
6. !=、<、<=、>、>= 保持这些操作符惯有含义
7. v.push_back(t) 在数组的最后添加一个值为t的数据
v.push_back(1); //把1和2压入vector 这样v[0]就是1,v[1]就是2
v.push_back(2);
8. v.pop_back(); // 弹出容器中最后一个元素(容器必须非空)
9. 我们可以用一个迭代器: vector<int>::iterator iter=v.begin();//定义一个可以迭代int型vector的迭代器iter,它指向v的首位
while(;iter!=v.end();iter++) cout<<(*iter);//iter++指的是向前迭代一位,直到iter到超出末端迭代器为止,输出迭代器指向的值
valarray对象最重要的几种操作
1. apply 将valarray数组的每一个值都用apply所接受到的函数进行计算
2. cshift 将valarray数组的数据进行循环移动,参数为正者左移为负就右移
3. max 返回valarray数组的最大值
4. min 返回valarray数组的最小值
5. resize 重新设置valarray数组大小,并对其进行初始化
6. shift 将valarray数组移动,参数为正者左移,为负者右移,移动后由0填充剩余位
7. size 得到数组的大小
8. sum 数组求和