GDI+を使用しjpg画像ピクセルサイズによりフォルダーに分類する

icon 項目のみ表示/展開表示の切り替え

概要

GDI+を使うと簡単にjpgファイルが扱える。
お遊びとして、指定したフォルダーに含まれるjpgファイルの画像ピクセルサイズにより下記のフォルダーに移動されます。

Quarter-VGA 320x240
CGA 640x240
VGA 640x480
Super-VGA 800x600
XGA 1024x768
Quad-VGA 1280x960
Super-XGA 1280x1024
SXGA+ 1400x1050
Ultra-XGA 1600x1200
Quad-XGA 2048x1536
Quad-Ultra-XGA 3200×2400
QXGA Wide 3840x2400

実行には再配布パッケージと、GDI+を使用するためGDIPLUS.DLLが必要である。実行ファイル作成には、GDIPLUS.LIBが必要。

画像のサイズは、IMAGEクラスのメンバー関数で取得しています。

ソース

ソースと実行ファイルのダウンロード

// jpgファイルのイメージをサイズで分類しそれぞれのフォルダーに移動する(指定されたフォルダーに含まれるjpgファイルを対象)
//      Windows 2000以降(Unicode,MBCS対応) Visual C++ 2005 Express
//      gdiplus.libをリンク
//      GDI+がインストールされていない場合は、gdiplus_dnld.exeを入手して解凍してgdiplus.dllをインストールすること。
/* 下記が作成されるフォルダーとイメージサイズ
Quarter-VGA 320x240 
CGA 640x240 
VGA 640x480 
Super-VGA 800x600 
XGA 1024x768 
Quad-VGA 1280x960 
Super-XGA 1280x1024 
SXGA+ 1400x1050 
Ultra-XGA 1600x1200 
Quad-XGA 2048x1536 
Quad-Ultra-XGA 3200×2400 
QXGA Wide 3840x2400 
*/

#include <windows.h>
#include <commctrl.h>
#include <direct.h> 
#include <shlobj.h>
#include <gdiplus.h>
#include <tchar.h>

using namespace Gdiplus;
GdiplusStartupInput gdiSI;
ULONG_PTR           gdiToken;

//      エンコーダーの取得

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
int GetDir(HWND hWnd,TCHAR* path,TCHAR* root);


int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,TCHAR* lpsCmdLine, int nCmdShow){
    GdiplusStartup(&gdiToken, &gdiSI, NULL);
        WIN32_FIND_DATA FindFileData;
        HANDLE hFind;
        CLSID     encoderClsid;
        if(GetEncoderClsid(L"image/jpeg", &encoderClsid)<0){
                MessageBox(0,TEXT("jpegエンコーダーが取得できませんでした。"),TEXT("エラー"),MB_OK);
                return (int)0;
        }
        TCHAR find_pass[MAX_PATH];
        GetDir(0,find_pass,0);
        TCHAR pass[MAX_PATH];
        TCHAR dtcFile[MAX_PATH];
        _stprintf_s(pass,sizeof(pass)/sizeof(TCHAR),TEXT( "%s\\*.jpg"),find_pass);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\small" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\QUARTER_VGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\CGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\VGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\Quad_VGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\Super_VGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\XGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\Super_XGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\SXGA_Plus" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\UXGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\QUXGA" ) ,find_pass);
        _tmkdir(dtcFile);
        _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR), TEXT( "%s\\QXGAW" ) ,find_pass);
        _tmkdir(dtcFile);
        hFind = FindFirstFile(pass, &FindFileData);
        if (hFind == INVALID_HANDLE_VALUE) {
                MessageBox(0, TEXT( "ファイルがみつかりませんでした。\n" ) , TEXT("エラー"),MB_OK);
        }else{
                do{

                        WCHAR wTitle[MAX_PATH];

#ifdef UNICODE
                        _stprintf_s(wTitle,sizeof(wTitle)/sizeof(TCHAR),TEXT("%s\\%s"),find_pass,FindFileData.cFileName);
#else
                        TCHAR szFile[MAX_PATH];
                        _stprintf_s(szFile,sizeof(szFile)/sizeof(TCHAR),TEXT("%s\\%s"),find_pass,FindFileData.cFileName);
                        MultiByteToWideChar(932,0,szFile,-1,wTitle,sizeof(wTitle)/sizeof(TCHAR));
#endif
                        Image& myImage=*Bitmap::FromFile(wTitle);   

                        int     px=myImage.GetWidth();  //      jpgファイルの画像の大きさ(横)
                        int py=myImage.GetHeight();             //      jpgファイルの画像の大きさ(縦)
                        int     l;
                        int     s;
                        if(px<py){
                                l=py;
                                s=px;
                        }else{
                                l=px;
                                s=py;
                        }
                        myImage.~Image();
                        if(l<320 && s<240){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\small\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<=640 && s<480){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\Quarter_VGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<800){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\VGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<1024){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\Super_VGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<1280){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\XGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<1400){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\Super_XGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<1600){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\SXGA_Plus\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<2048){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\UXGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else if(l<3200){
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\QUXGA\\%s" ) ,find_pass,FindFileData.cFileName);
                        }else{
                                _stprintf_s(dtcFile,sizeof(dtcFile)/sizeof(TCHAR) , TEXT( "%s\\QXGAW\\%s" ) ,find_pass,FindFileData.cFileName);
                        }                       
#ifdef UNICODE
                        MoveFile(wTitle,dtcFile);
#else
                        MoveFile(szFile,dtcFile);
#endif
                }while((FindNextFile(hFind,&FindFileData)));
                FindClose(hFind);
        }
    GdiplusShutdown(gdiToken);
        MessageBox(0,TEXT("終了しました"),TEXT("メッセージ"),MB_OK);

        return (int)0;
}

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {
         UINT  num = 0;
         UINT  size = 0;
         ImageCodecInfo* pImageCodecInfo;
         GetImageEncodersSize(&num, &size);
         if(size == 0)
                  return -1;
         pImageCodecInfo = (ImageCodecInfo*)new char[size];
         if(pImageCodecInfo == NULL)
                  return -1;
         GetImageEncoders(num, size, pImageCodecInfo);
         for(UINT n=0; n<num; ++n) {
                  if( wcscmp(pImageCodecInfo[n].MimeType, format) == 0 ) {
                           *pClsid = pImageCodecInfo[n].Clsid;
                           delete pImageCodecInfo;
                           return n;
                  }
         }
         delete pImageCodecInfo;
         return -1;
}
int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);


//      ディレクトリ名を取得するコモンダイアログを表示する

int GetDir(HWND hWnd,TCHAR* path,TCHAR* root){
        BROWSEINFO bInfo; 
        LPITEMIDLIST pIDList; 
        bInfo.hwndOwner = hWnd; // ダイアログの親ウインドウのハンドル 
        bInfo.pidlRoot =NULL; // ルートフォルダをデスクトップフォルダとする 
        bInfo.pszDisplayName =path; //szDisplayName; // フォルダ名を受け取るバッファへのポインタ 
        bInfo.lpszTitle = TEXT("サイズを選別するフォルダの選択"); // ツリービューの上部に表示される文字列 
        bInfo.ulFlags = BIF_RETURNONLYFSDIRS; // 表示されるフォルダの種類を示すフラグ 
        bInfo.lpfn = BrowseCallbackProc; // BrowseCallbackProc関数のポインタ 
        bInfo.lParam = NULL; 
        pIDList = SHBrowseForFolder(&bInfo); 
        if(pIDList == NULL){
                path[0]=_TEXT('\0');
                return FALSE; //何も選択されなかった場合 
        }else{
                if(!SHGetPathFromIDList(pIDList, path))
                        return FALSE;//変換に失敗 
                CoTaskMemFree( pIDList );// pIDListのメモリを開放 
                return TRUE; 
        }
}
//      上記ダイアログのコールバック関数

int __stdcall BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData){
        return 0; 
}