一个小时左右随便赶出来的,使用体验不是很好……批量添加图片时不要一次性选择太多图片,不然程序会崩溃,我上次2MB左右的图片一次性选择40张左右没问题。
环境 VS2019,用的easyx绘图库,20200902版。
源码,自己编译:
#include <easyx.h>
#include <iostream>
#include <string>
#include <io.h>
#include <Shlobj.h>
#include <comutil.h>
#include <conio.h>
#pragma comment(lib, "comsuppw.lib")
using namespace std;
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
string wtos(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
wstring stow(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
// 得到某目录下的文件列表,不含文件夹
// in: path 文件目录(例如:E:\\abc)
// out: pList 文件列表指针,只需要传入空指针即可,格式是每个下标对应一个绝对路径名
// out: nListNum 文件列表内文件个数
// in: type 指定搜索某格式的文件,默认为 "\\*" 代表要遍历所有的类型,如改成 "\\*.jpg" 表示遍历jpg类型文件
void GetFileListString(string path, string*& pList, int* nListNum, string type = "\\*")
{
long hFile = 0, num = 0;
_finddata_t fileInfo;
string pathName, exdName, * list = NULL;
if ((hFile = _findfirst(pathName.assign(path).append(type).c_str(), &fileInfo)) == -1) return;
do
{
// 这一项是文件夹
if (fileInfo.attrib & _A_SUBDIR)
continue;
// 这一项是文件
else
{
// 更新string数组
num++;
string* new_list = new string[num];
for (int i = 0; i < num - 1; i++)
new_list[i] = list[i];
if (num - 1 > 0) delete[] list;
else if (num > 0) delete list;
list = new_list;
// 如果末尾有"\\",则无需再在绝对路径中加"\\"
if (path[path.size() - 1] == '\\')
list[num - 1] = path + fileInfo.name;
// 如果末尾无"\\",则需要再在绝对路径中加"\\"
else
list[num - 1] = path + "\\" + fileInfo.name;
}
} while (_findnext(hFile, &fileInfo) == 0);
_findclose(hFile);
pList = list;
*nListNum = num;
}
// 选择目录
// wnd:父窗口句柄
// title:选择文件夹对话框标题
wstring SelectFolder(HWND wnd = NULL, wstring title = L"选择一个文件夹")
{
TCHAR szBuffer[MAX_PATH] = { 0 };
BROWSEINFO bi = { 0 };
bi.hwndOwner = wnd; // 父窗口句柄,为NULL表示对话框是非模态的
bi.pszDisplayName = szBuffer; // 接收文件夹的缓冲区
bi.lpszTitle = title.c_str(); // 对话框标题
bi.ulFlags = BIF_NEWDIALOGSTYLE;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (SHGetPathFromIDList(idl, szBuffer)) {
return szBuffer;
}
else {
MessageBox(NULL, TEXT("请选择一个文件夹"), NULL, MB_ICONERROR);
return NULL;
}
}
// 图片拉伸
// width, height 拉伸后的图片大小
// img 原图像
void ImageToSize(int width, int height, IMAGE* img)
{
IMAGE* pOldImage = GetWorkingImage();
SetWorkingImage(img);
IMAGE temp_image(width, height);
StretchBlt(
GetImageHDC(&temp_image), 0, 0, width, height,
GetImageHDC(img), 0, 0,
getwidth(), getheight(),
SRCCOPY
);
Resize(img, width, height);
putimage(0, 0, &temp_image);
SetWorkingImage(pOldImage);
}
int main()
{
string* p_strFileList;
wstring* p_strNotes;
IMAGE* p_imgs;
int nFileNum;
int nIndex = 0; // 当前操作的图像下标
initgraph(1024, 768);
MessageBox(GetHWnd(), L"请将所有图片都存放到一个文件夹内,里面只能有图片。按下确定后开始选择这个文件夹", L"提示", MB_OK);
wstring wstrFolder = SelectFolder(GetHWnd());
// 列举目录下的所有文件
GetFileListString(wtos(wstrFolder), p_strFileList, &nFileNum);
// 加载图像
p_imgs = new IMAGE[nFileNum];
for(int i=0;i<nFileNum;i++)
loadimage(&p_imgs[i], stow(p_strFileList[i]).c_str());
p_strNotes = new wstring[nFileNum];
while (true)
{
if (KEY_DOWN(VK_LEFT))
{
if(nIndex > 0)
nIndex--;
_getch();
}
if (KEY_DOWN(VK_RIGHT))
{
if (nIndex < nFileNum - 1)
nIndex++;
_getch();
}
IMAGE now = p_imgs[nIndex];
ImageToSize(getwidth(), getheight(), &now);
putimage(0,0,&now);
WCHAR str[64] = { 0 };
wsprintf(str, L"第 %d 张,共 %d 张,按左右键切换图片,按空格编辑备注,按Shift+回车表示完成所有图片的备注", nIndex + 1, nFileNum);
outtextxy(0,0, str);
if (KEY_DOWN(VK_SPACE))
{
WCHAR note[2048] = { 0 };
InputBox(note, 2048, 0, 0, 0, 640, 480, true);
RECT rctNull = { 0,0,0,0 };
int height = drawtext(note, &rctNull, NULL);
SetWorkingImage(&p_imgs[nIndex]);
Resize(&p_imgs[nIndex], getwidth(), getheight() + height);
RECT rctText = { 0, getheight() - height ,getwidth(),getheight()};
drawtext(note, &rctText, NULL);
SetWorkingImage(NULL);
_getch();
}
if (KEY_DOWN(VK_SHIFT) && KEY_DOWN(VK_RETURN))
{
MessageBox(GetHWnd(), L"按确定后,选择一个文件夹存储修改后的图像", L"提示", MB_OK);
wstring wstrSaveFolder = SelectFolder(GetHWnd());
wstring* p_wstrImgFilePath = new wstring[nFileNum];
for (int i = 0; i < nFileNum; i++)
{
// 存储该文件的相对路径名到path
wstring path;
int index = 0;
for (int j = p_strFileList[i].size() - 1; j >= 0; j--)
{
if (p_strFileList[i][j] == '\\')
{
index = j;
break;
}
}
for (int k = index + 1; k < (int)p_strFileList[i].size();k++)
path += p_strFileList[i][k];
// 存储新文件的绝对路径名到p_wstrImgFilePath
p_wstrImgFilePath[i] = wstrSaveFolder + L"\\" + path;
// 保存图像
saveimage(p_wstrImgFilePath[i].c_str(), &p_imgs[i]);
}
MessageBox(GetHWnd(), L"完成", L"提示", MB_OK);
return 0;
}
Sleep(100);
}
closegraph();
return 0;
}