huidong

首页 | 会员登录 | 关于争取 2022 寒假做出汇东网 Ver3.0.0 !
搜索文章


一个小时左右随便赶出来的,使用体验不是很好……批量添加图片时不要一次性选择太多图片,不然程序会崩溃,我上次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;
}




返回首页


Copyright (C) 2018-2022 huidong