// ■GDIを使えばもっと多くの画像形式を読み込める // @「gdiplus.lib」を入手して、ソースプログラムと同じファイルに格納する。 // A「既存項目の追加」を選んで「gdiplus.lib」を選択する。 // B「myWin.h」はその他と同じ #include "myWin.h" // GDI+用宣言 #include #include #include using namespace Gdiplus; // GDI+用領域宣言 static ULONG_PTR gdiToken ; static GdiplusStartupInput gdiStIn; static EncoderParameters* encParam ; static ULONG clDpth, quality, trans; static Status stat ; static CLSID encClsID; static Image *image ; static Bitmap *pBitmap; static UINT width,height ; static ImageType type; static PixelFormat pxForm ; static REAL hor, ver; static BOOL notFirst=FALSE ; //image,pBitmapを解放するためのフラグ // 一般領域宣言 static HDC hdc; static TCHAR str[255];static HANDLE hF; static OPENFILENAME CC;BYTE dtBuff[16]; static TCHAR strFile[1024],strFileTitle[128]; static TCHAR sFilter[]=TEXT("Jpeg Files\0*.jpg\0PNG Files\0*.png\0") TEXT("GIF Files\0*.gif\0BMP Files\0*.bmp\0") TEXT("TIFF Files\0*.tif\0All Files\0*.*\0"); static double scale=1.0; //エンコーダクラスIDの設定 int getEncoderClassID(const WCHAR *format,CLSID * pClsid){ int R=-1;UINT N=0, Msize=0;// 失敗のとき-1 ImageCodecInfo * pImgCdIn=NULL; GetImageEncodersSize(&N, &Msize); if(Msize==0) return R ; if((pImgCdIn=(ImageCodecInfo*)malloc(Msize))==NULL) return R; GetImageEncoders(N, Msize,pImgCdIn); for(UINT j=0;jGetRawFormat(&guid); //画像書式 width =image->GetWidth(); height=image->GetHeight();//サイズ hor =image->GetHorizontalResolution(); //解像度 ver =image->GetVerticalResolution(); type =image->GetType(); //ファイル型 pxForm =image->GetPixelFormat(); //色書式 notFirst=TRUE; dspImgFormat(guid, type, pxForm, width, height, hor, ver); scale=1.0; InvalidateRect(hw,NULL,TRUE); } } void setFormat(TCHAR *str,TCHAR format[]){//拡張子から int L=lstrlen(str),ID, i; //ファイル形式を生成 for(ID=L-1;ID>=0 && str[ID]!=TCHAR('.');ID--); if(ID<0 || ID==(L-1)) lstrcpy(format,TEXT("image/bmp")); else{ lstrcpy(format,TEXT("image/")); for( ID++,i=6 ; IDParameter[i].Guid = Guid; encParam->Parameter[i].Type = Type; encParam->Parameter[i].NumberOfValues = Num; encParam->Parameter[i].Value = Value; } void setEncoderParam(){ //trans = EncoderValueTransformRotate90;//確認用 clDpth = 24; quality = 80; //(quality: 0〜100) encParam->Count = 2; //パラメータ数指定 //setEParam(0, EncoderTransformation, EncoderParameterValueTypeLong, 1, &trans ); setEParam(0, EncoderQuality , EncoderParameterValueTypeLong, 1, &quality); setEParam(1, EncoderColorDepth , EncoderParameterValueTypeLong, 1, &clDpth ); } void fileSave(HWND hw){ if(GetSaveFileName(&CC)){ TCHAR format[128]; setFormat(strFile,format); if(getEncoderClassID(format,&encClsID)<0) MessageBox(hw,TEXT("この形式はサポートしていません"), TEXT("エラー"),MB_OK); else{ setEncoderParam();//パラーメータ設定。変換なしのときedcParam=NULL if((stat = image->Save(strFile,&encClsID,encParam))==Ok) MessageBox(hw,TEXT("成功"),TEXT("正常終了"),MB_OK); else MessageBox(hw,TEXT("失敗"),TEXT("エラー" ),MB_OK); } } } void procLButtonUp(HWND hw, WPARAM wp,LPARAM lp){//ファイル入力 scale*=1.1; InvalidateRect(hw,NULL,TRUE); } void procRButtonUp(HWND hw, WPARAM wp,LPARAM lp){//ファイル出力 scale /= 1.1; InvalidateRect(hw,NULL,TRUE); } static HMENU hm,hmFile,hmDisplay,hmLarge,hmSmall; enum file_ID{ F_OPEN=5000, F_SAVE, F_EXIT}; enum display_ID{ D_NORML=5010, D_LARGE, D_SMALL}; enum large_ID{ L_2=5020, L_5, L_10}; enum small_ID{ S_2=5030, S_5, S_10}; void procCreate(HWND hw, WPARAM wp,LPARAM lp){ MENUITEMINFO mi; hm=CreateMenu(); hmFile=CreateMenu(); hmDisplay=CreateMenu(); hmLarge=CreateMenu();hmSmall=CreateMenu(); mi.cbSize=sizeof(MENUITEMINFO); mi.fMask=MIIM_TYPE|MIIM_SUBMENU; mi.fType=MFT_STRING; mi.hSubMenu=hmFile ; mi.dwTypeData=TEXT("ファイル(&F)"); InsertMenuItem(hm,0,TRUE, &mi); mi.hSubMenu=hmDisplay; mi.dwTypeData=TEXT("表示(&D)" ); InsertMenuItem(hm,1,TRUE, &mi); mi.fMask=MIIM_TYPE|MIIM_ID; mi.wID=F_OPEN; mi.dwTypeData=TEXT("開く(&O)");InsertMenuItem(hmFile,0,TRUE, &mi); mi.wID=F_SAVE; mi.dwTypeData=TEXT("保存(&S)");InsertMenuItem(hmFile,1,TRUE, &mi); mi.fType=MFT_SEPARATOR ;InsertMenuItem(hmFile,2,TRUE, &mi); mi.fType=MFT_STRING; mi.wID=F_EXIT; mi.dwTypeData=TEXT("終了(&X)");InsertMenuItem(hmFile,3,TRUE, &mi); //表示メニュー mi.wID=D_NORML; mi.dwTypeData=TEXT("通常(&N)");InsertMenuItem(hmDisplay,0,TRUE, &mi); mi.fMask=MIIM_TYPE|MIIM_SUBMENU; mi.hSubMenu=hmLarge; mi.dwTypeData=TEXT("拡大(&L)");InsertMenuItem(hmDisplay,1,TRUE, &mi); mi.hSubMenu=hmSmall; mi.dwTypeData=TEXT("縮小(&S)");InsertMenuItem(hmDisplay,2,TRUE, &mi); mi.fMask=MIIM_TYPE|MIIM_ID; mi.wID=L_2 ; mi.dwTypeData=TEXT("2倍(&D)" );InsertMenuItem(hmLarge,0,TRUE, &mi); mi.wID=L_5 ; mi.dwTypeData=TEXT("5倍(&F)" );InsertMenuItem(hmLarge,1,TRUE, &mi); mi.wID=L_10 ; mi.dwTypeData=TEXT("10倍(&T)");InsertMenuItem(hmLarge,2,TRUE, &mi); mi.wID=S_2 ; mi.dwTypeData=TEXT(" 1/2(&D)" );InsertMenuItem(hmSmall,0,TRUE, &mi); mi.wID=S_5 ; mi.dwTypeData=TEXT(" 1/5(&F)" );InsertMenuItem(hmSmall,1,TRUE, &mi); mi.wID=S_10 ; mi.dwTypeData=TEXT("1/10(&T)");InsertMenuItem(hmSmall,2,TRUE, &mi); SetMenu(hw, hm); CC.lStructSize =sizeof(OPENFILENAME); CC.hwndOwner =hw ; CC.hInstance =hInstance; CC.lpstrFilter =sFilter ; CC.nFilterIndex =1; CC.lpstrCustomFilter=NULL ; CC.nMaxCustFilter=0; CC.lpstrFile =strFile ; CC.nMaxFile =1024; CC.lpstrFileTitle =strFileTitle; CC.nMaxFileTitle =128; CC.lpstrInitialDir =TEXT("D:\\"); CC.lpstrTitle =TEXT("GDI+で表示"); CC.lpstrDefExt =TEXT("jpg") ; CC.FlagsEx =0; CC.Flags = OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_DONTADDTORECENT| OFN_NOTESTFILECREATE; GdiplusStartup(&gdiToken,&gdiStIn,NULL);//GDI++開始 encParam=(EncoderParameters*) malloc(sizeof(EncoderParameters)+4*sizeof(EncoderParameter)); fileOpen(hw); } void procPaint(HWND hw, WPARAM wp,LPARAM lp){//再描画処理 PAINTSTRUCT ps; hdc=BeginPaint(hw,&ps); Graphics graphics(hdc); graphics.DrawImage(pBitmap,(int)0,(int)0, (int)(width*scale), (int)(height*scale)); EndPaint(hw,&ps); } void setScale(HWND hw,double S){//スケールセット scale=S; InvalidateRect(hw,NULL,TRUE); } void procExit(HWND hw){ if(MessageBox(hw, TEXT("終了してもよろしいですか"), TEXT("画像ビューア"),MB_OKCANCEL)==IDOK) PostMessage(hw,WM_DESTROY, 0,0); } void procCommand(HWND hw, WPARAM wp,LPARAM lp){//コマンド判別 switch(LOWORD(wp)){ case D_NORML:setScale(hw,1);break; case L_2 :setScale(hw, scale*2 );break; case L_5 :setScale(hw, scale*5 );break; case L_10:setScale(hw, scale*10);break; case S_2 :setScale(hw, scale/2 );break; case S_5 :setScale(hw, scale/5 );break; case S_10:setScale(hw, scale/10);break; case F_EXIT: procExit(hw);break; case F_OPEN: fileOpen(hw);break; case F_SAVE: fileSave(hw);break; } } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : if(notFirst){delete image; delete pBitmap;} GdiplusShutdown(gdiToken); PostQuitMessage(0) ;return 0; case WM_CREATE : procCreate(hw,wp,lp);return 0; case WM_LBUTTONUP: procLButtonUp(hw,wp,lp);return 0; case WM_COMMAND : procCommand(hw,wp,lp);return 0; case WM_RBUTTONUP: procRButtonUp(hw,wp,lp);return 0; case WM_PAINT : procPaint (hw,wp,lp);return 0; } return DefWindowProc(hw,msg,wp,lp); }