照片处理小工具三合一设计到实现(一)
2017-11-14 17:22
190 查看
首先上目前的软件截图:
下载地址:http://download.csdn.net/download/autumoonchina/10118243
主要功能如下:
支持照片归类,文件归类,照片缩放(包括gif动画缩放),以及克隆EXIF等功能。
实际上写这个软件,也只是因为之前我的妻子跟我提到了照片归类的需求,她的照片比较多,手机导出的照片分类比较杂乱,还有空文件夹,但是如果人工整理的话比较麻烦,于是我决定自己写一个文件归类的软件,网上这类工具也挺多,但是具体到我的需求,总是各种不同,要不软件还有一些限制,总觉得还是自己写比较好,以后也可以扩充功能,于是自己写了这个软件的第一个版本。
图片分类的代码比较简单,读取EXIF信息,然后按照拍摄日期分类。
想到除了整理照片,还可以整理其他的文件,所以当时增加了整理所有文件的功能,按照“最后一次修改时间”
关键代码为:
恢复功能是必不可少的,所以增加了log记录,可以恢复原来的文件结构,毕竟谁都有可能弄错,所以准备一碗后悔药是必要的。
关键代码:
于是第一个版本就完成了,实现了文件的整理,这里发现一个问题就是,多线程会出问题,因为重命名文件的速度本身就很快,用多线程反而会出现资源抢占的问题,以上所以这个模块最终选择了单线程实现,但是保留了多线程的接口。
(未完待续)
下载地址:http://download.csdn.net/download/autumoonchina/10118243
主要功能如下:
支持照片归类,文件归类,照片缩放(包括gif动画缩放),以及克隆EXIF等功能。
实际上写这个软件,也只是因为之前我的妻子跟我提到了照片归类的需求,她的照片比较多,手机导出的照片分类比较杂乱,还有空文件夹,但是如果人工整理的话比较麻烦,于是我决定自己写一个文件归类的软件,网上这类工具也挺多,但是具体到我的需求,总是各种不同,要不软件还有一些限制,总觉得还是自己写比较好,以后也可以扩充功能,于是自己写了这个软件的第一个版本。
图片分类的代码比较简单,读取EXIF信息,然后按照拍摄日期分类。
int CClassifyFiles::MovePicsByTime(const char* pStr, const char* pSavePath, const int& nProcessIndex) { std::string strRootDir = CStdStr::AddSlashIfNeeded(CMfcStrFile::CString2Char(g_strDir)) + "autumoon\\"; if (_access(strRootDir.c_str(), 0) != 0) { if (!CreateDirectory(CString(strRootDir.c_str()), NULL)) { return -1; } } std::string strPicTime; std::string strYearMonth; if (Get_ExifTime(pStr, strPicTime)) { strYearMonth = strPicTime.substr(0, 7); strYearMonth = CStdStr::RepalceAll(strYearMonth, ":"); } else { CString strLastWriteTime = GetModifyTime(CString(pStr)); strYearMonth = std::string(CMfcStrFile::CString2Char(strLastWriteTime)); } std::string strSaveDir = strRootDir + strYearMonth; if (_access(strSaveDir.c_str(), 0) != 0) { if (!CreateDirectory(CString(strSaveDir.c_str()), NULL)) { return -1; } } std::string strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(pStr); if (CStdFile::IfAccessFile(strSavePath)) { int nNum = 0; do { ++nNum; strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(pStr, false) + CStdTpl::ConvertToString(nNum) + CStdStr::GetSuffixOfFile(pStr); } while (CStdFile::IfAccessFile(strSavePath)); } if (strSavePath != std::string(pStr)) { rename(pStr, strSavePath.c_str()); } g_Mutex.Lock(); g_mLogs.insert(std::make_pair(std::string(pStr), strSavePath)); g_Mutex.Unlock(); return 0; }
想到除了整理照片,还可以整理其他的文件,所以当时增加了整理所有文件的功能,按照“最后一次修改时间”
关键代码为:
int CClassifyFiles::MoveFilesByTime(const char* pStr, const char* pSavePath, const int& nProcessIndex) { std::string strDir = CMfcStrFile::CString2Char(g_strDir); std::string strRootDir = CStdStr::AddSlashIfNeeded(strDir) + "autumoon\\"; if (_access(strRootDir.c_str(), 0) != 0) { if (!CreateDirectory(CString(strRootDir.c_str()), NULL)) { return -1; } } CString strLastWriteTime = GetModifyTime(CString(pStr)); std::string strYearMonth = std::string(CMfcStrFile::CString2Char(strLastWriteTime)); std::string strSaveDir = strRootDir + strYearMonth; if (_access(strSaveDir.c_str(), 0) != 0) { if (!CreateDirectory(CString(strSaveDir.c_str()), NULL)) { return -1; } } std::string strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(pStr); int nNum = 0; if (CStdFile::IfAccessFile(strSavePath)) { do { ++nNum; strSavePath = CStdStr::AddSlashIfNeeded(strSaveDir) + CStdStr::GetNameOfFile(pStr, false) + CStdTpl::ConvertToString(nNum) + CStdStr::GetSuffixOfFile(pStr); } while (CStdFile::IfAccessFile(strSavePath)); } if (rename(pStr, strSavePath.c_str()) < 0) { rename(pStr, strSavePath.c_str()); } g_Mutex.Lock(); g_mLogs.insert(std::make_pair(std::string(pStr), strSavePath)); g_Mutex.Unlock(); return 0; }
恢复功能是必不可少的,所以增加了log记录,可以恢复原来的文件结构,毕竟谁都有可能弄错,所以准备一碗后悔药是必要的。
关键代码:
int CClassifyFiles::RestoreFile(const char* pStr, const char* pSavePath, const int& nProcessIndex) { std::string strOldPath = g_mLogs[std::string(pStr)]; std::string strOldDir = CStdStr::GetDirOfFile(strOldPath); if (_access(strOldDir.c_str(), 0) != 0) { CStdDir::CreateDir(strOldDir); } if (strOldPath != std::string(pStr)) { rename(pStr, strOldPath.c_str()); } return 0; }
于是第一个版本就完成了,实现了文件的整理,这里发现一个问题就是,多线程会出问题,因为重命名文件的速度本身就很快,用多线程反而会出现资源抢占的问题,以上所以这个模块最终选择了单线程实现,但是保留了多线程的接口。
(未完待续)
相关文章推荐
- 照片处理小工具三合一设计到实现(三)
- 照片处理小工具三合一设计到实现(二)
- [原创]分表处理设计思想和实现
- 如何设计数据库实现灵活处理权限分配
- 基于哈希查找的字库设计与实现及其自动生成工具的实现
- 异步处理任务工具类(AsyncTask)实现多张图片的下载(已知url)
- 自定义表单的设计工具及运行期实现
- 百度兴趣点下载工具设计和实现
- VBA的临时表管理工具设计与实现
- Linux内核设计与实现之中断处理
- 游戏服务器端如何设计和实现可视化工具
- 开源夏令营之foldcolumn工具及解决方案(五)数值精度处理实现
- 我的本科毕业设计(非水文,设计了一个新算法):一种字符编码猜测工具的实现方法
- 第五章 工作流定义工具的设计与实现(七)
- 数据库分表处理设计思想和实现
- Linux内核设计与实现——7 中断与中断处理(8)——中断控制
- 公司评估综合业务处理系统的设计与实现
- 基于GUI的简易图像处理系统设计与实现
- mysql分表处理基本设计思想和实现
- 病历智能处理引擎的设计、实现和应用