Home > ソフトウェア > MagicPNG > MagicPNG100.zip > Src > MainDialog.cpp
//MainDialog.cpp //メインダイアログ //`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^` // MagicPNG Ver.1.00 by x@rgs // Released under NYSL Version 0.9982 // //`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^` #include"StdAfx.h" #include"MainDialog.h" #include<math.h> using namespace sslib; namespace{ //イメージファイルからリサイズしてHBITMAPを取得 HBITMAP getThumbnailFromImage(LPCTSTR file_path,int thumbnail_width,int thumbnail_height){ Gdiplus::Bitmap* bitmap=Gdiplus::Bitmap::FromFile(file_path); if(bitmap->GetLastStatus()!=Gdiplus::Ok)return NULL; HBITMAP hbitmap=NULL; bitmap->GetHBITMAP(0,&hbitmap); //リサイズしない場合 if(!thumbnail_width&&!thumbnail_height){ SAFE_DELETE(bitmap); return hbitmap; } int dest_width=0; int dest_height=0; int src_width=bitmap->GetWidth(); int src_height=bitmap->GetHeight(); SAFE_DELETE(bitmap); if(thumbnail_width){ //幅基準で作成 if(thumbnail_width<src_width){ float x=(float)thumbnail_width/src_width; float y=(float)thumbnail_width/src_height; //縮小後のサイズ dest_width=(int)(min(x,y)*src_width); dest_height=(int)(min(x,y)*src_height); }else{ //幅か高さのどちらかが指定サイズ以下ならリサイズしない return hbitmap; } }else{ //高さ基準で作成 if(thumbnail_height<src_height){ float x=(float)thumbnail_height/src_width; float y=(float)thumbnail_height/src_height; //縮小後のサイズ dest_width=(int)(min(x,y)*src_width); dest_height=(int)(min(x,y)*src_height); }else{ //幅か高さのどちらかが指定サイズ以下ならリサイズしない return hbitmap; } } HDC hdc_screen=::GetDC(NULL); HDC hdc_tmp=::CreateCompatibleDC(hdc_screen); ::SelectObject(hdc_tmp,hbitmap); HDC hdc_memory=::CreateCompatibleDC(hdc_screen); HBITMAP hbitmap_result=::CreateCompatibleBitmap(hdc_screen,dest_width,dest_height); HGDIOBJ hobj_old=::SelectObject(hdc_memory,hbitmap_result); ::SetStretchBltMode(hdc_memory,HALFTONE); HPALETTE hpalette=::CreateHalftonePalette(hdc_memory); HPALETTE hpalette_old=::SelectPalette(hdc_memory,hpalette,false); ::RealizePalette(hdc_memory); ::StretchBlt(hdc_memory,0,0,dest_width,dest_height,hdc_tmp,0,0,src_width,src_height,SRCCOPY); ::SelectPalette(hdc_memory,hpalette_old,false); ::DeleteObject(hpalette); ::ReleaseDC(NULL,hdc_screen); ::SelectObject(hdc_memory,hobj_old); ::DeleteDC(hdc_tmp); ::DeleteObject(hbitmap); return hbitmap_result; } //サムネイルを設定 void setButtonThumbnail(HWND hButton,LPCTSTR image_path,int width,int height){ HBITMAP hbitmap=NULL; if((hbitmap=getThumbnailFromImage(image_path,width,height))!=NULL){ SendMessage(hButton,BM_SETIMAGE,(WPARAM)IMAGE_BITMAP,(LPARAM)hbitmap); } } struct Options{ double gamma; unsigned fade1; unsigned int fade2; unsigned int shift; //fadeについては後で/255.0すること Options():gamma(0.023),fade1(220),fade2(210),shift(10){} }; Options options; const Options default_options; BYTE trans1(BYTE num){ return BYTE(floor((pow((num*(options.fade1/255.0)+options.shift)/255.0,options.gamma))*255.0)); } BYTE trans2(BYTE num){ double r=num*(options.fade2/255.0); return BYTE((r>0.0)?floor(r+0.5):ceil(r-0.5)); } int getEncoderCLSID(const TCHAR* format,CLSID* clsid){ unsigned int num_encoders=0,size=0; Gdiplus::GetImageEncodersSize(&num_encoders,&size); if(size==0)return -1; Gdiplus::ImageCodecInfo* pImageCodecInfo=new Gdiplus::ImageCodecInfo[size]; if(pImageCodecInfo==NULL)return -1; Gdiplus::GetImageEncoders(num_encoders,size,pImageCodecInfo); for(unsigned int index=0;index<num_encoders;++index){ if(lstrcmp(pImageCodecInfo[index].MimeType,format)==0){ *clsid=pImageCodecInfo[index].Clsid; SAFE_DELETE(pImageCodecInfo); return index; } } SAFE_DELETE(pImageCodecInfo); return -1; } } INT_PTR MainDialog::DropButton::onDropFiles(HDROP drop_handle){ DropFiles drop_files(drop_handle); RECT rc; ::GetWindowRect(handle(),&rc); setButtonThumbnail(handle(),drop_files.getFile(0).c_str(),rc.right-rc.left,0); ::SetWindowText(handle(),drop_files.getFile(0).c_str()); return true; } INT_PTR MainDialog::onInitDialog(WPARAM wparam,LPARAM lparam){ //アイコンの設定(タイトルバー) setIcon(IDI_ICON1); //タイトルの設定(タイトルバー) ::SetWindowText(handle(),(tstring(_T("MagicPNG Ver."))+SOFTWARE_VERSION).c_str()); //サブクラス化してドロップでファイルを受け取る m_src1_button=new DropButton(handle(),IDC_BUTTON_SRC1); m_src2_button=new DropButton(handle(),IDC_BUTTON_SRC2); if(m_src1_button==NULL||m_src2_button==NULL){ SAFE_DELETE(m_src1_button); SAFE_DELETE(m_src2_button); return false; } { //引数解析 std::vector<tstring>& filepaths=static_cast<CommandArgument*>(param())->filepaths(); for(std::vector<tstring>::size_type i=0,size=filepaths.size();i<size;++i){ DropButton* ptr=(i==0)?m_src1_button:(i==1)?m_src2_button:NULL; RECT rc; if(ptr==NULL)break; ::GetWindowRect(ptr->handle(),&rc); setButtonThumbnail(ptr->handle(),filepaths[i].c_str(),rc.right-rc.left,0); ::SetWindowText(ptr->handle(),filepaths[i].c_str()); } } //デフォルト設定に sendMessage(WM_COMMAND,MAKEWPARAM(IDC_BUTTON_DEFAULT,0),0); return true; } INT_PTR MainDialog::onCommand(WPARAM wparam,LPARAM lparam){ switch(LOWORD(wparam)){ case IDC_BUTTON_SRC1: case IDC_BUTTON_SRC2:{ FileDialog file_dialog; tstring file_path; if(!file_dialog.doModalOpen(&file_path, handle(), _T("全てのファイル (*.*)\0*.*\0\0"), _T("処理したいファイルを選択してください"))){ return false; } RECT rc; ::GetWindowRect(getDlgItem(LOWORD(wparam)),&rc); setButtonThumbnail(getDlgItem(LOWORD(wparam)),file_path.c_str(),rc.right-rc.left,0); ::SetWindowText(getDlgItem(LOWORD(wparam)),file_path.c_str()); break; } case IDC_BUTTON_DEFAULT: options=default_options; ::SetWindowText(getDlgItem(IDC_EDIT_GAMMA),format(_T("%f"),options.gamma).c_str()); ::SetWindowText(getDlgItem(IDC_EDIT_FADE1),format(_T("%d"),options.fade1).c_str()); ::SetWindowText(getDlgItem(IDC_EDIT_FADE2),format(_T("%d"),options.fade2).c_str()); ::SetWindowText(getDlgItem(IDC_EDIT_SHIFT),format(_T("%d"),options.shift).c_str()); break; case IDC_BUTTON_CREATE:{ tstring src1_path,src2_path,output_path; std::vector<TCHAR> buffer(MAX_PATH); ::GetWindowText(getDlgItem(IDC_BUTTON_SRC1),&buffer[0],buffer.size()); src1_path.assign(&buffer[0]); ::GetWindowText(getDlgItem(IDC_BUTTON_SRC2),&buffer[0],buffer.size()); src2_path.assign(&buffer[0]); if(!path::fileExists(src1_path.c_str())|| !path::fileExists(src2_path.c_str())){ ::MessageBox(handle(), _T("元画像を選択してください。"), (tstring(_T("MagicPNG Ver."))+SOFTWARE_VERSION).c_str(), MB_ICONEXCLAMATION); return false; } Gdiplus::Bitmap* src1_bitmap=Gdiplus::Bitmap::FromFile(src1_path.c_str(),TRUE); Gdiplus::Bitmap* src2_bitmap=Gdiplus::Bitmap::FromFile(src2_path.c_str(),TRUE); if(src1_bitmap==NULL||src2_bitmap==NULL){ ::MessageBox(handle(), _T("画像を開くことができません。"), (tstring(_T("MagicPNG Ver."))+SOFTWARE_VERSION).c_str(), MB_ICONEXCLAMATION); SAFE_DELETE(src1_bitmap); SAFE_DELETE(src2_bitmap); return false; } if(src1_bitmap->GetWidth()!=src2_bitmap->GetWidth()|| src1_bitmap->GetHeight()!=src2_bitmap->GetHeight()){ ::MessageBox(handle(), _T("同じサイズの画像を選択してください。"), (tstring(_T("MagicPNG Ver."))+SOFTWARE_VERSION).c_str(), MB_ICONEXCLAMATION); SAFE_DELETE(src1_bitmap); SAFE_DELETE(src2_bitmap); return false; } SAFE_DELETE(src1_bitmap); SAFE_DELETE(src2_bitmap); FileDialog file_dialog; if(!file_dialog.doModalSave(&output_path, handle(), _T("PNGファイル (*.png)\0*.png\0\0"), _T("保存ファイル名を入力してください"), NULL, NULL, _T("png"))){ return false; } if(output_path.empty())return false; if(src1_path==output_path|| src2_path==output_path|| src1_path==src2_path)return false; //PNG作成 createMagicPNG(output_path.c_str(),src1_path.c_str(),src2_path.c_str()); break; } default: break; } switch(HIWORD(wparam)){ case EN_CHANGE: std::vector<TCHAR> buffer(MAX_PATH); tstring buffer_str; switch(LOWORD(wparam)){ case IDC_EDIT_GAMMA: case IDC_EDIT_FADE1: case IDC_EDIT_FADE2: case IDC_EDIT_SHIFT: ::GetWindowText(getDlgItem(LOWORD(wparam)),&buffer[0],buffer.size()); buffer_str.assign(&buffer[0]); if(!buffer_str.empty()){ switch(LOWORD(wparam)){ case IDC_EDIT_GAMMA: options.gamma=_tstof(buffer_str.c_str()); break; case IDC_EDIT_FADE1: options.fade1=_tstoi(buffer_str.c_str()); break; case IDC_EDIT_FADE2: options.fade2=_tstoi(buffer_str.c_str()); break; case IDC_EDIT_SHIFT: options.shift=_tstoi(buffer_str.c_str()); break; default: break; } } break; } break; } return false; } void MainDialog::createMagicPNG(const TCHAR* output_path,const TCHAR* src1_path,const TCHAR* src2_path){ Gdiplus::Bitmap* src1_bitmap=Gdiplus::Bitmap::FromFile(src1_path,TRUE); Gdiplus::Bitmap* src2_bitmap=Gdiplus::Bitmap::FromFile(src2_path,TRUE); Gdiplus::Bitmap* output_bitmap=new Gdiplus::Bitmap(src1_bitmap->GetWidth()*2,src1_bitmap->GetHeight()*2,PixelFormat32bppARGB); if(src1_bitmap==NULL||src2_bitmap==NULL||output_bitmap==NULL){ SAFE_DELETE(src1_bitmap); SAFE_DELETE(src2_bitmap); SAFE_DELETE(output_bitmap); return; } Gdiplus::BitmapData output_bitmap_data,src1_bitmap_data,src2_bitmap_data; output_bitmap->LockBits(NULL,Gdiplus::ImageLockModeWrite,PixelFormat32bppARGB,&output_bitmap_data); src1_bitmap->LockBits(NULL,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,&src1_bitmap_data); src2_bitmap->LockBits(NULL,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,&src2_bitmap_data); RGBQUAD* output_rgb=NULL; int bytes=output_bitmap_data.Stride; unsigned char* ptr=(unsigned char*)output_bitmap_data.Scan0; unsigned int width=output_bitmap->GetWidth(); unsigned int height=output_bitmap->GetHeight(); for(unsigned int y=0;y<height;y++){ output_rgb=(RGBQUAD*)ptr; for(unsigned int x=0;x<width;x++){ if(x%2==0&&y%2==0){ RGBQUAD* src1_rgb=(RGBQUAD*)src1_bitmap_data.Scan0+x/2+(y/2*src1_bitmap_data.Stride/sizeof(RGBQUAD)); output_rgb->rgbRed=trans1(src1_rgb->rgbRed); output_rgb->rgbGreen=trans1(src1_rgb->rgbGreen); output_rgb->rgbBlue=trans1(src1_rgb->rgbBlue); output_rgb->rgbReserved=src1_rgb->rgbReserved; }else{ RGBQUAD* src2_rgb=(RGBQUAD*)src2_bitmap_data.Scan0+x/2+(y/2*src2_bitmap_data.Stride/sizeof(RGBQUAD)); output_rgb->rgbRed=trans2(src2_rgb->rgbRed); output_rgb->rgbGreen=trans2(src2_rgb->rgbGreen); output_rgb->rgbBlue=trans2(src2_rgb->rgbBlue); output_rgb->rgbReserved=src2_rgb->rgbReserved; } output_rgb++; } if(y+1<height){ ptr+=bytes; } } output_bitmap->UnlockBits(&output_bitmap_data); src1_bitmap->UnlockBits(&src1_bitmap_data); src2_bitmap->UnlockBits(&src2_bitmap_data); //gAMA(PropertyTagGamma)の値を変更 unsigned long rational[]={100000,unsigned long(100000*options.gamma)}; Gdiplus::PropertyItem property_item; property_item.id=PropertyTagGamma; property_item.length=sizeof(unsigned long)*2; property_item.type=PropertyTagTypeRational; property_item.value=&rational; output_bitmap->SetPropertyItem(&property_item); CLSID clsid; if(getEncoderCLSID(_T("image/png"),&clsid)>=0){ //出力 if(output_bitmap->Save(output_path,&clsid,NULL)==Gdiplus::Ok){ ::MessageBox(handle(), format(_T("'%s' を作成しました。"),output_path).c_str(), (tstring(_T("MagicPNG Ver."))+SOFTWARE_VERSION).c_str(), MB_ICONINFORMATION); } } SAFE_DELETE(src1_bitmap); SAFE_DELETE(src2_bitmap); SAFE_DELETE(output_bitmap); }
Home > ソフトウェア > MagicPNG > MagicPNG100.zip > Src > MainDialog.cpp