最近需要缩放N多图片,
找遍了互联网也没有找到方便使用的批量缩放工具..
趁着周末写一个练手..
#include <iostream> #include <vector> #include <list> #include <string> #include <iterator> #include <functional> #include <memory> #include <fstream> #include <sstream> #include <Shlwapi.h> #include <Windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") #pragma comment(lib, "Shlwapi.lib") inline std::wstring getDirectory(const std::wstring &fullname) { auto findIndex = fullname.find_last_of('\\'); return findIndex != std::wstring::npos ? fullname.substr(, findIndex + ) : std::wstring(); } inline std::wstring getFullName(const std::wstring &fullname) { auto findIndex = fullname.find_last_of('\\'); return findIndex != std::wstring::npos ? fullname.substr(findIndex + ) : std::wstring(); } template <class T1, class T2> inline T1 parseTo(const T2 &t) { static std::wstringstream sstream; T1 r; sstream << t; sstream >> r; sstream.clear(); return r; } CLSID findCLSID(const std::wstring &format) { CLSID clsid = { }; auto num = 0u; auto size = 0u; Gdiplus::GetImageEncodersSize(&num, &size); ) { auto pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)); if (pImageCodecInfo != nullptr) { GetImageEncoders(num, size, pImageCodecInfo); ; j< num; ++j) { if (format == pImageCodecInfo[j].MimeType) { clsid = pImageCodecInfo[j].Clsid; break; } } free(pImageCodecInfo); } } return clsid; } void forEachFileList( const std::wstring &fileListName, const std::function<void (const std::wstring &)> &handler) { std::wifstream ifile(fileListName); if (ifile) { std::wstring fileName; while (std::getline(ifile, fileName)) { handler(fileName); } ifile.close(); } } int createSaveDirector(const std::wstring &director) { auto result = true; if (!PathFileExists(director.c_str())) { result = CreateDirectory(director.c_str(), nullptr) != ; } return result; } void saveImage(Gdiplus::Bitmap *pImage, const CLSID &clsid, const std::wstring &saveFile) { auto director = getDirectory(saveFile); director.append(L"\\save\\"); if (createSaveDirector(director)) { director.append(getFullName(saveFile)); std::wcout << L"save image file: " << director << std::endl; pImage->Save(director.c_str(), &clsid); } } void scaleImage(const std::wstring &fileName, const CLSID &clsid, float scalex, float scaley) { Gdiplus::Bitmap image(fileName.c_str()); if (image.GetLastStatus() == Gdiplus::Ok) { auto srcWidth= image.GetWidth(); auto srcHeight = image.GetHeight(); auto dstWidth = srcWidth * scalex; auto dstHeight = srcHeight * scaley; Gdiplus::Bitmap newImage((u_int)dstWidth, (u_int)dstHeight); Gdiplus::Graphics graphics(&newImage); graphics.DrawImage(&image, 0u, 0u, dstWidth, dstHeight); saveImage(&newImage, clsid, fileName); } } void run(const std::wstring &fileList, float scalex, float scaley) { u_long token; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartup(&token, &input, nullptr); { auto clsid = findCLSID(L"image/png"); || clsid.Data2 != || clsid.Data3 != ) { forEachFileList( fileList, std::bind(scaleImage, std::placeholders::_1, clsid, scalex, scaley)); } } Gdiplus::GdiplusShutdown(token); } int wmain(int argn, wchar_t *argc[]) { std::locale(std::locale::global(std::locale("chs"))); std::wcout << argn << std::endl; ) { std::wcout << L"参数格式: " << L"imglist.txt scalex scaley" << std::endl; } else { run(argc[], parseTo<]), parseTo<])); } std::wcout << L"run done." << std::endl; std::wcin.get(); ; }
使用说明:
在控制台下运行即可.
运行需要三个参数分别是: 需要缩放的图片路径列表, x缩放之, y缩放值.
第一个参数是一个包含了需要被缩放的图片路径列表, 是纯文本文件, 可以用cmd命令来生成:
for /r %%i in(.,*) do echo %%i>>.\filelist.txt