#include #include #include #include"resource.h" #include"hensu.h" #include"bmp_io.h" #include"clip_board.h" #include"thresh_color.h" #include"HSB.h" LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); ATOM InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE,int); LRESULT CALLBACK MyDlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp); char szClassName[]="template"; int iWidth,iHeight; HINSTANCE hInst; int t_min,t_max; int WINAPI WinMain(HINSTANCE hCurInst,HINSTANCE hPrevInst, LPSTR lpsCmdLine,int nCmdShow) { MSG msg; BOOL bRet; hInst=hCurInst; if(!InitApp(hCurInst)) return FALSE; if(!InitInstance(hCurInst,nCmdShow)) return FALSE; while((bRet=GetMessage(&msg,NULL,0,0))!=0){ if(bRet==-1){ MessageBox(NULL,"GetMessageエラー","Error",MB_OK); break; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst) { WNDCLASSEX wc; wc.cbSize=sizeof(WNDCLASSEX); wc.style=CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc=WndProc; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hInstance=hInst; wc.hIcon=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0,0, LR_DEFAULTSIZE|LR_SHARED); wc.hCursor=(HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0,0, LR_DEFAULTSIZE|LR_SHARED); wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName="MYMENU"; wc.lpszClassName=(LPCTSTR)szClassName; wc.hIconSm=(HICON)LoadImage(NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0,0, LR_DEFAULTSIZE|LR_SHARED); return RegisterClassEx(&wc); } BOOL InitInstance(HINSTANCE hInst,int nCmdShow) { HWND hWnd; hWnd=CreateWindow(szClassName, "第9章 色で抜き出す", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 840, 720, NULL, NULL, hInst, NULL); if(!hWnd) return FALSE; ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); return TRUE; } enum LINE {MIN,MAX}; enum PICTURE {FRONT,BACK,SYNTH}; LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) { static BMP_IO f_bmp,b_bmp; static LPBITMAPINFO lpbiInfo,lpbiInfoHue; static LPDWORD lpPixelFront,lpPixelBack,lpPixelSynth,lpPixelShow,lpPixelHue; static LPBYTE key; static double *hue,*sat,*bri; static enum LINE line; static enum PICTURE pic; static double ww,hh; static int min_line,max_line; static long hist[360]; char text[64]; int r,g,b; int h,i; HDROP hDrop; char szFileName[256]; HMENU hMenu; MENUITEMINFO mi; HDC hdc; PAINTSTRUCT ps; HPEN hPen,hOldPen; switch(msg){ case WM_CREATE: DragAcceptFiles(hWnd,TRUE); ww=1; hh=1; min_line=270; max_line=280; line=MAX; pic=FRONT; lpPixelHue=(LPDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, 10*360*sizeof(DWORD)+sizeof(BITMAPINFO)); lpbiInfoHue=(LPBITMAPINFO)(lpPixelHue+10*360); lpbiInfoHue->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpbiInfoHue->bmiHeader.biWidth=10; lpbiInfoHue->bmiHeader.biHeight=-360; lpbiInfoHue->bmiHeader.biPlanes=1; lpbiInfoHue->bmiHeader.biBitCount=32; lpbiInfoHue->bmiHeader.biCompression=BI_RGB; for(h=0;h<360;h++){ if(h<60){ r=255; g=h*255/60; b=0; }else if(h<120){ r=255-(h-60)*255/60; g=255; b=0; }else if(h<180){ r=0; g=255; b=(h-120)*255/60; }else if(h<240){ r=0; g=255-(h-180)*255/60; b=255; }else if(h<300){ r=(h-240)*255/60; g=0; b=255; }else{ //hue<360 r=255; g=0; b=255-(h-300)*255/60; } for(i=0;i<10;i++) lpPixelHue[i+h*10]=(r<<16)+(g<<8)+b; } break; case WM_DROPFILES: hDrop=(HDROP)wp; DragQueryFile(hDrop,0,szFileName,sizeof(szFileName)); DragFinish(hDrop); if(pic==FRONT){ if(!f_bmp.bmp_in(szFileName,hWnd)) break; lpbiInfo=&f_bmp.biInfo; lpPixelFront=f_bmp.lpPixel; iWidth=f_bmp.iWidth; iHeight=f_bmp.iHeight; if(lpPixelShow!=NULL) HeapFree(GetProcessHeap(),0,lpPixelShow); lpPixelShow=(LPDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, iWidth*iHeight*sizeof(DWORD) +iWidth*iHeight*sizeof(BYTE) +3*iWidth*iHeight*sizeof(double)); key=(LPBYTE)(lpPixelShow+iWidth*iHeight); hue=(double *)(key+iWidth*iHeight); sat=hue+iWidth*iHeight; bri=hue+iWidth*iHeight*2; CopyMemory(lpPixelShow,lpPixelFront,iWidth*iHeight*sizeof(DWORD)); ww=1; hh=1; RGBtoHSB(lpPixelFront,hue,sat,bri); histgram_Hue(hue,hist); }else if(pic==BACK){ if(!b_bmp.bmp_in(szFileName,hWnd)) break; lpbiInfo=&b_bmp.biInfo; lpPixelBack=b_bmp.lpPixel; iWidth=b_bmp.iWidth; iHeight=b_bmp.iHeight; if(lpPixelSynth!=NULL) HeapFree(GetProcessHeap(),0,lpPixelSynth); lpPixelSynth=(LPDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, iWidth*iHeight*sizeof(DWORD)); CopyMemory(lpPixelShow,lpPixelBack,iWidth*iHeight*sizeof(DWORD)); ww=1; hh=1; } InvalidateRect(hWnd,NULL,TRUE); break; case WM_PAINT: hdc=BeginPaint(hWnd,&ps); if(min_line>=300 && min_line<300+360){ sprintf(text,"色相%d度(最小線): %d個(%lf%%)", min_line-300,hist[min_line-300], (double)hist[min_line-300]/(iWidth*iHeight)*100.0); TextOut(hdc,300,210,text,(int)strlen(text)); } if(max_line>=300 && max_line<300+360){ sprintf(text,"色相%d度(最大線): %d個(%lf%%)", max_line-300,hist[max_line-300], (double)hist[max_line-300]/(iWidth*iHeight)*100.0); TextOut(hdc,300,230,text,(int)strlen(text)); } StretchDIBits(hdc,5,300,10,360, 0,0,10,360,lpPixelHue,lpbiInfoHue, DIB_RGB_COLORS,SRCCOPY); for(i=0;i<360;i++){ MoveToEx(hdc,20,300+i,NULL); LineTo(hdc,20+hist[i]/2,300+i); } hPen=CreatePen(PS_SOLID,1,RGB(0,0,255)); hOldPen=(HPEN)SelectObject(hdc,hPen); MoveToEx(hdc,0,min_line,NULL); LineTo(hdc,2048,min_line); SelectObject(hdc,hOldPen); DeleteObject(hPen); hPen=CreatePen(PS_SOLID,1,RGB(255,0,0)); hOldPen=(HPEN)SelectObject(hdc,hPen); MoveToEx(hdc,0,max_line,NULL); LineTo(hdc,2048,max_line); SelectObject(hdc,hOldPen); DeleteObject(hPen); StretchDIBits(hdc,0,0,(int)(ww*iWidth),(int)(hh*iHeight), 0,0,iWidth,iHeight,lpPixelShow,lpbiInfo, DIB_RGB_COLORS,SRCCOPY); EndPaint(hWnd,&ps); break; case WM_COMMAND: switch(LOWORD(wp)){ case IDM_COPY: CopyDIB(hWnd,lpPixelShow); break; case IDM_PASTE: if(pic==FRONT){ if(!f_bmp.PasteDIBSection(hWnd)) break; lpbiInfo=&f_bmp.biInfo; lpPixelFront=f_bmp.lpPixel; iWidth=f_bmp.iWidth; iHeight=f_bmp.iHeight; if(lpPixelShow!=NULL) HeapFree(GetProcessHeap(),0,lpPixelShow); lpPixelShow=(LPDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, iWidth*iHeight*sizeof(DWORD) +iWidth*iHeight*sizeof(BYTE) +3*iWidth*iHeight*sizeof(double)); key=(LPBYTE)(lpPixelShow+iWidth*iHeight); hue=(double *)(key+iWidth*iHeight); sat=hue+iWidth*iHeight; bri=hue+iWidth*iHeight*2; CopyMemory(lpPixelShow,lpPixelFront,iWidth*iHeight*sizeof(DWORD)); ww=1; hh=1; RGBtoHSB(lpPixelFront,hue,sat,bri); histgram_Hue(hue,hist); }else if(pic==BACK){ if(!b_bmp.PasteDIBSection(hWnd)) break; lpbiInfo=&b_bmp.biInfo; lpPixelBack=b_bmp.lpPixel; iWidth=b_bmp.iWidth; iHeight=b_bmp.iHeight; if(lpPixelSynth!=NULL) HeapFree(GetProcessHeap(),0,lpPixelSynth); lpPixelSynth=(LPDWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, iWidth*iHeight*sizeof(DWORD)); CopyMemory(lpPixelShow,lpPixelBack,iWidth*iHeight*sizeof(DWORD)); ww=1; hh=1; } InvalidateRect(hWnd,NULL,TRUE); break; case IDM_DELETE: pic=FRONT; HeapFree(GetProcessHeap(),0,lpPixelShow); HeapFree(GetProcessHeap(),0,lpPixelSynth); f_bmp.~BMP_IO(); b_bmp.~BMP_IO(); lpPixelFront=NULL; lpPixelShow=NULL; hue=NULL; lpPixelBack=NULL; lpPixelSynth=NULL; ZeroMemory(hist,360*sizeof(long)); break; case IDM_HARD: if(DialogBox(hInst,"MYDLG",hWnd,(DLGPROC)MyDlgProc)==IDOK){ pic=FRONT; hard_mask(lpPixelFront,lpPixelShow,key,t_min); } break; case IDM_SOFT: if(DialogBox(hInst,"MYDLG",hWnd,(DLGPROC)MyDlgProc)==IDOK){ pic=FRONT; soft_mask(lpPixelFront,lpPixelShow,key,t_min,t_max); } break; case IDM_SYNTH: pic=SYNTH; s_synth(lpPixelFront,lpPixelBack,lpPixelSynth,key); CopyMemory(lpPixelShow,lpPixelSynth,iWidth*iHeight*sizeof(DWORD)); break; case IDM_FRONT: pic=FRONT; if(lpPixelShow!=NULL && lpPixelFront!=NULL) CopyMemory(lpPixelShow,lpPixelFront,iWidth*iHeight*sizeof(DWORD)); break; case IDM_BACK: pic=BACK; if(lpPixelBack!=NULL) CopyMemory(lpPixelShow,lpPixelBack,iWidth*iHeight*sizeof(DWORD)); else ZeroMemory(lpPixelShow,iWidth*iHeight*sizeof(DWORD)); break; case IDM_SYNTH_PIC: pic=SYNTH; if(lpPixelSynth!=NULL) CopyMemory(lpPixelShow,lpPixelSynth,iWidth*iHeight*sizeof(DWORD)); else ZeroMemory(lpPixelShow,iWidth*iHeight*sizeof(DWORD)); break; case IDM_ZOOM1: ww=1; hh=1; break; case IDM_ZOOM2: ww=2; hh=2; break; case IDM_ZOOM3: ww=3; hh=3; break; case IDM_ZOOM4: ww=4; hh=4; break; case IDM_ZOOM02: ww=1.0/2; hh=1.0/2; break; case IDM_ZOOM03: ww=1.0/3; hh=1.0/3; break; case IDM_ZOOM04: ww=1.0/4; hh=1.0/4; break; } InvalidateRect(hWnd,NULL,TRUE); break; case WM_INITMENU: hMenu=GetMenu(hWnd); mi.cbSize=sizeof(MENUITEMINFO); mi.fMask=MIIM_STATE; if(pic==FRONT){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_FRONT,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_FRONT,FALSE,&mi); } if(lpPixelShow!=NULL){ if(pic==BACK){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_BACK,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_BACK,FALSE,&mi); } if(pic==SYNTH){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_SYNTH_PIC,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_SYNTH_PIC,FALSE,&mi); } }else{ mi.fState=MFS_GRAYED; SetMenuItemInfo(hMenu,IDM_BACK,FALSE,&mi); SetMenuItemInfo(hMenu,IDM_SYNTH_PIC,FALSE,&mi); } if(lpPixelSynth!=NULL){ mi.fState=MFS_ENABLED; SetMenuItemInfo(hMenu,IDM_SYNTH,FALSE,&mi); }else{ mi.fState=MFS_GRAYED; SetMenuItemInfo(hMenu,IDM_SYNTH,FALSE,&mi); } if(IsClipboardFormatAvailable(CF_DIB)){ mi.fState=MFS_ENABLED; SetMenuItemInfo(hMenu,IDM_PASTE,FALSE,&mi); }else{ mi.fState=MFS_GRAYED; SetMenuItemInfo(hMenu,IDM_PASTE,FALSE,&mi); } if(ww==1){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM1,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM1,FALSE,&mi); } if(ww==2){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM2,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM2,FALSE,&mi); } if(ww==3){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM3,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM3,FALSE,&mi); } if(ww==4){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM4,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM4,FALSE,&mi); } if(ww==1.0/2){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM02,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM02,FALSE,&mi); } if(ww==1.0/3){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM03,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM03,FALSE,&mi); } if(ww==1.0/4){ mi.fState=MFS_CHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM04,FALSE,&mi); }else{ mi.fState=MFS_UNCHECKED; SetMenuItemInfo(hMenu,IDM_ZOOM04,FALSE,&mi); } DrawMenuBar(hWnd); break; case WM_KEYDOWN: switch(LOWORD(wp)){ case VK_UP: if(line==MAX) max_line--; else min_line--; break; case VK_DOWN: if(line==MAX) max_line++; else min_line++; break; case VK_RETURN: if(min_line>=300 && min_line<300+360 && max_line>=300 && max_line<300+360) thresh_Hue(lpPixelFront,lpPixelShow,hue,min_line-300,max_line-300); else CopyMemory(lpPixelShow,lpPixelFront,iWidth*iHeight*sizeof(DWORD)); break; case VK_TAB: if(line==MAX) line=MIN; else line=MAX; break; } InvalidateRect(hWnd,NULL,TRUE); break; case WM_CLOSE: HeapFree(GetProcessHeap(),0,lpPixelHue); HeapFree(GetProcessHeap(),0,lpPixelShow); HeapFree(GetProcessHeap(),0,lpPixelSynth); DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd,msg,wp,lp); } return 0; } LRESULT CALLBACK MyDlgProc(HWND hDlg,UINT msg,WPARAM wp,LPARAM lp) { static HWND hEdit1,hEdit2,hUpdown1,hUpdown2; static int last_min,last_max; switch(msg){ case WM_INITDIALOG: last_min=t_min; last_max=t_max; hEdit1=GetDlgItem(hDlg,IDC_EDIT1); hEdit2=GetDlgItem(hDlg,IDC_EDIT2); hUpdown1=GetDlgItem(hDlg,IDC_SPIN1); hUpdown2=GetDlgItem(hDlg,IDC_SPIN2); SendMessage(hUpdown1,UDM_SETBUDDY,(WPARAM)hEdit1,0); SendMessage(hUpdown1,UDM_SETRANGE32,(WPARAM)-255,(LPARAM)255); SendMessage(hUpdown1,UDM_SETPOS,0,(LPARAM)MAKELONG((short)last_min,0)); SendMessage(hUpdown2,UDM_SETBUDDY,(WPARAM)hEdit2,0); SendMessage(hUpdown2,UDM_SETRANGE32,(WPARAM)-255,(LPARAM)255); SendMessage(hUpdown2,UDM_SETPOS,0,(LPARAM)MAKELONG((short)last_max,0)); return TRUE; case WM_COMMAND: switch(LOWORD(wp)){ case IDOK: if(last_min>32767) t_min=last_min-65536; else t_min=last_min; if(last_max>32767) t_max=last_max-65536; else t_max=last_max; EndDialog(hDlg,IDOK); return TRUE; case IDCANCEL: EndDialog(hDlg,IDCANCEL); return TRUE; } if((HWND)lp==hEdit1 && HIWORD(wp)==EN_CHANGE){ last_min=(int)SendMessage(hUpdown1,UDM_GETPOS,0,0); return TRUE; } if((HWND)lp==hEdit2 && HIWORD(wp)==EN_CHANGE){ last_max=(int)SendMessage(hUpdown2,UDM_GETPOS,0,0); return TRUE; } return FALSE; } return FALSE; }