001: #include <windows.h>
002: #include <wingdi.h>
003: #include <commctrl.h>
004: #include "wingui.h"
005:
006:
007:
008: HINSTANCE hAppInst;
009: HWND hAppWnd;
010: int iWidth,iHeight,iLength;
011: int iSize,biSize,bmpLoad;
012: int iOrgWidth,iOrgHeight;
013: int iGHist[512],iCHist[3][512];
014: LPBYTE lpOrgBMP,lpBMP;
015: LPBITMAPINFO lpBInfo;
016: extern MenuInfo MI[];
017:
018: void IP_init();
019:
020:
021: int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
022: LPSTR lpsCmdLine, int nCmdShow)
023: {
024: LPCTSTR szClassName = "BMP画像処理";
025: bmpLoad = 0; iWidth = 300; iHeight = 200;
026:
027:
028:
029: if(!hPrevInst){
030: if(!InitApp(hCurInst,szClassName)) return 0;
031: hAppInst = hCurInst;
032: }
033:
034:
035:
036: if(!InitInstance(hCurInst,szClassName,lpsCmdLine,nCmdShow)){
037: return 0;
038: }
039:
040:
041:
042: IP_init();
043:
044:
045:
046: MSG msg;
047: while(GetMessage(&msg,NULL,0,0)){
048: TranslateMessage(&msg);
049: DispatchMessage(&msg);
050: }
051: return msg.wParam;
052: }
053:
054:
055:
056: BOOL InitApp(HINSTANCE hInst, LPCSTR szClassName)
057: {
058: WNDCLASSEX wc;
059: wc.cbSize = sizeof(wc);
060: wc.style = CS_HREDRAW | CS_VREDRAW;
061: wc.lpfnWndProc = WndProc;
062: wc.cbClsExtra = 0;
063: wc.cbWndExtra = 0;
064: wc.hInstance = hInst;
065: wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
066: wc.hCursor = LoadCursor(NULL,IDC_ARROW);
067: wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
068: wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
069: wc.lpszMenuName = NULL;
070: wc.lpszClassName = (LPCSTR)szClassName;
071: return (RegisterClassEx(&wc));
072: }
073:
074:
075:
076: BOOL InitInstance(HINSTANCE hInst,LPCSTR szClassName,
077: LPSTR lpsCmdLine,int nCmdShow)
078: {
079: TCHAR lpStr[256]; LPSTR ifile;
080:
081:
082:
083: if(strlen(lpsCmdLine)) {
084: ifile = lpsCmdLine;
085:
086: if(!LoadBMP(ifile,lpBInfo,lpOrgBMP))
087: return 0;
088:
089: set_image_size(lpBInfo);
090:
091: lpBMP=(LPBYTE)GlobalAlloc(GPTR,iLength*iHeight);
092: CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight);
093: }
094:
095: if(bmpLoad) wsprintf(lpStr,"%s %d*%d Pixel %dBit",
096: ifile,iWidth,iHeight,
097: lpBInfo->bmiHeader.biBitCount);
098: else wsprintf(lpStr,"BMP画像処理");
099:
100:
101:
102: HWND hWnd;
103: hWnd = CreateWindow(szClassName,lpStr,
104: WS_OVERLAPPEDWINDOW,
105: CW_USEDEFAULT,
106: CW_USEDEFAULT,
107: 15+iWidth,
108: 70+iHeight,
109: NULL,
110: NULL,
111: hInst,
112: NULL);
113: if(!hWnd) return FALSE;
114:
115: DragAcceptFiles(hWnd,TRUE);
116:
117: ShowWindow(hWnd,nCmdShow);
118:
119: UpdateWindow(hWnd);
120:
121: hAppWnd = hWnd;
122: return TRUE;
123: }
124:
125:
126:
127: LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg,
128: WPARAM wParam, LPARAM lParam)
129: {
130: static HWND hwB1,hwB2,hwB3,hwSel;
131: static UINT s,mi,mlen,mlen_max;
132: TCHAR szFn[MAX_PATH];
133: HDC hdc; HDROP hDrop; PAINTSTRUCT ps;
134: switch(iMsg){
135: case WM_CHAR:
136: if(wParam=='q') SendMessage(hwnd,WM_DESTROY,NULL,NULL); break;
137: case WM_CREATE: {
138: InitCommonControls();
139:
140: hwB1=CreateWindow("Button","開く", WS_CHILD | WS_VISIBLE,
141: 5,5,60,25,hwnd,(HMENU)ID_OPEN,hAppInst,NULL);
142: hwB2=CreateWindow("Button","保存", WS_CHILD | WS_VISIBLE,
143: 65,5,60,25,hwnd,(HMENU)ID_SAVE,hAppInst,NULL);
144: hwB3=CreateWindow("Button","実行", WS_CHILD | WS_VISIBLE,
145: 125,5,60,25,hwnd,(HMENU)ID_IP,hAppInst,NULL);
146:
147: mi = mlen_max = 0;
148: while(MI[mi].menu!=NULL){
149: if(mlen_max < strlen(MI[mi].menu))
150: mlen_max = strlen(MI[mi].menu);
151: mi++;
152: }
153: mlen = 8*(mlen_max+1);
154: hwSel=CreateWindow("COMBOBOX",NULL,
155: WS_CHILD|WS_VISIBLE|CBS_DROPDOWN,
156: 190,5,mlen,200,hwnd,(HMENU)0,hAppInst,NULL);
157: mi = 0;
158: while(MI[mi].menu!=NULL){
159: SendMessage(hwSel,CB_ADDSTRING,0,(LPARAM)MI[mi].menu);
160: mi++;
161: }
162: SendMessage(hwSel,CB_SETCURSEL,0,1);
163: } break;
164: case WM_COMMAND:
165: switch(LOWORD(wParam)){
166: case 'q':
167: SendMessage(hwnd,WM_DESTROY,NULL,NULL); break;
168: case ID_OPEN:
169: if(OpenFile(hwnd,szFn)){
170: reLoadBMP(szFn);
171: }
172: break;
173: case ID_SAVE:
174: if(SaveFile(hwnd,szFn)){
175: SaveBMP(szFn,lpBInfo,lpBMP);
176: }
177: break;
178: case ID_IP:
179: if(bmpLoad){
180: s=SendMessage(hwSel,CB_GETCURSEL,0,0);
181: MI[s].proc();
182: InvalidateRgn(hwnd,NULL,TRUE);
183: UpdateWindow(hwnd);
184: }
185: break;
186: }
187: break;
188: case WM_DROPFILES:
189:
190: hDrop=(HDROP)wParam;
191: DragQueryFile(hDrop,0,szFn,MAX_PATH);
192: DragFinish(hDrop);
193:
194: reLoadBMP(szFn);
195: break;
196: case WM_PAINT:
197: if(bmpLoad){
198: hdc=BeginPaint(hwnd,&ps);
199: StretchDIBits(hdc,4,35,iWidth,iHeight,
200: 0,0,iWidth,iHeight,lpBMP,lpBInfo,
201: DIB_RGB_COLORS,SRCCOPY);
202: EndPaint(hwnd,&ps);
203: }
204: break;
205: case WM_DESTROY:
206: GlobalFree(lpBInfo);
207: GlobalFree(lpOrgBMP);
208: PostQuitMessage(0);
209: break;
210: }
211: return DefWindowProc(hwnd,iMsg,wParam,lParam);
212: }
213:
214:
215:
216: void GetWinPos(HWND hWnd,UINT *x,UINT *y)
217: {
218: WINDOWPLACEMENT wndpl;
219: GetWindowPlacement(hWnd,&wndpl);
220: *x = wndpl.rcNormalPosition.left;
221: *y = wndpl.rcNormalPosition.top;
222: return;
223: }
224:
225:
226:
227: void set_image_size(LPBITMAPINFO bInfo)
228: {
229: iWidth = bInfo->bmiHeader.biWidth;
230: iHeight = bInfo->bmiHeader.biHeight;
231: iSize = iWidth*iHeight;
232: iOrgWidth = iWidth;
233: iOrgHeight = iHeight;
234:
235: if((iWidth*3)%4==0) iLength = iWidth*3;
236: else iLength = iWidth*3+(4-(iWidth*3)%4);
237: biSize = iHeight*iLength;
238:
239: bmpLoad = 1;
240: }
241:
242: void set_ip_window(int xsize,int ysize)
243: {
244: if(xsize && ysize){
245: iWidth = xsize;
246: iHeight = ysize;
247: } else {
248: if(xsize > iWidth) return;
249: if(ysize > iHeight) return;
250: iWidth = iOrgWidth;
251: iHeight = iOrgHeight;
252: }
253: iSize = iWidth*iHeight;
254:
255: if((iWidth*3)%4==0) iLength = iWidth*3;
256: else iLength = iWidth*3+(4-(iWidth*3)%4);
257: biSize = iHeight*iLength;
258:
259: lpBInfo->bmiHeader.biWidth = iWidth;
260: lpBInfo->bmiHeader.biHeight = iHeight;
261: }
262:
263:
264:
265: UINT OpenFile(HWND hWnd, LPTSTR lpFname)
266: {
267: static OPENFILENAME ofn;
268: TCHAR szFn[MAX_PATH],szFt[MAX_PATH];
269: FillMemory(szFn,MAX_PATH,0);
270:
271: ofn.lStructSize = sizeof(OPENFILENAME);
272: ofn.hwndOwner = hWnd;
273: ofn.hInstance = NULL;
274: ofn.lpstrFilter =
275: "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0";
276: ofn.lpstrCustomFilter = NULL;
277: ofn.nMaxCustFilter = 0;
278: ofn.nFilterIndex = 1;
279: ofn.lpstrFile = szFn;
280: ofn.nMaxFile = 255;
281: ofn.lpstrFileTitle = szFt;
282: ofn.nMaxFileTitle = 255;
283: ofn.lpstrInitialDir = NULL;
284: ofn.lpstrTitle = "Bitmap";
285: ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
286: ofn.nFileOffset = 0;
287: ofn.nFileExtension = 0;
288: ofn.lpstrDefExt = "bmp";
289: ofn.lCustData = 0;
290: ofn.lpfnHook = NULL;
291: ofn.lpTemplateName = NULL;
292:
293: if(!GetOpenFileName(&ofn)) return FALSE;
294: wsprintf(lpFname,szFn);
295: return TRUE;
296: }
297:
298:
299:
300: UINT SaveFile(HWND hWnd, LPTSTR lpFname)
301: {
302: static OPENFILENAME ofn;
303: TCHAR szFn[MAX_PATH],szFt[MAX_PATH];
304: FillMemory(szFn,MAX_PATH,0);
305:
306: ofn.lStructSize = sizeof(OPENFILENAME);
307: ofn.hwndOwner = hWnd;
308: ofn.hInstance = NULL;
309: ofn.lpstrFilter =
310: "Bitmap(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0";
311: ofn.lpstrCustomFilter = NULL;
312: ofn.nMaxCustFilter = 0;
313: ofn.nFilterIndex = 1;
314: ofn.lpstrFile = szFn;
315: ofn.nMaxFile = 255;
316: ofn.lpstrFileTitle = szFt;
317: ofn.nMaxFileTitle = 255;
318: ofn.lpstrInitialDir = NULL;
319: ofn.lpstrTitle = "Bitmap";
320: ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
321: ofn.nFileOffset = 0;
322: ofn.nFileExtension = 0;
323: ofn.lpstrDefExt = "bmp";
324: ofn.lCustData = 0;
325: ofn.lpfnHook = NULL;
326: ofn.lpTemplateName = NULL;
327:
328: if(!GetSaveFileName(&ofn)) return FALSE;
329: wsprintf(lpFname,szFn);
330: return TRUE;
331: }
332:
333:
334:
335: UINT LoadBMP(LPCTSTR lpFname,LPBITMAPINFO& biBuf,LPBYTE& lpBuf)
336: {
337: HANDLE hdlBmp;
338: BITMAPFILEHEADER bfhBmp;
339: DWORD dwdFileSize =0;
340: DWORD dwdPixelsSize=0;
341: RGBQUAD cpal[256];
342:
343:
344:
345: hdlBmp=CreateFile(lpFname,GENERIC_READ,0,NULL,OPEN_EXISTING,
346: FILE_ATTRIBUTE_NORMAL,NULL);
347: if(hdlBmp==INVALID_HANDLE_VALUE){
348: MessageBox(NULL,"読込みに失敗しました",NULL,MB_OK);
349: return FALSE;
350: }
351:
352:
353:
354: ReadFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL);
355: biBuf = (LPBITMAPINFO)GlobalAlloc(GPTR,sizeof(BITMAPINFO));
356: ReadFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL);
357:
358:
359:
360: if(biBuf->bmiHeader.biBitCount<24){
361: for(UINT i=0;i<biBuf->bmiHeader.biClrUsed;i++)
362: ReadFile(hdlBmp,&cpal[i],sizeof(RGBQUAD),&dwdFileSize,NULL);
363: }
364:
365:
366:
367: dwdPixelsSize=((biBuf->bmiHeader.biWidth+3)&0xfffffffc) *
368: biBuf->bmiHeader.biHeight*3;
369: lpBuf=(LPBYTE)GlobalAlloc(GPTR,dwdPixelsSize);
370: if(biBuf->bmiHeader.biBitCount<24){
371: UINT x,y,iysize,ixsize,ileng;
372: LPBYTE inBuf;
373:
374: biBuf->bmiHeader.biBitCount = 24;
375: iysize = biBuf->bmiHeader.biHeight;
376: ixsize = biBuf->bmiHeader.biWidth;
377: ileng = ixsize;
378: if((ileng%4)!=0) ileng=((ileng/4)+1)*4;
379: dwdPixelsSize = ileng * iysize;
380: inBuf=(LPBYTE)GlobalAlloc(GPTR,dwdPixelsSize);
381: ReadFile(hdlBmp,inBuf,dwdPixelsSize,&dwdFileSize,NULL);
382: for(y=0;y<iysize;y++) for(x=0;x<ixsize;x++){
383: lpBuf[(x+y*ileng)*3+2] = cpal[inBuf[x+y*ileng]].rgbRed;
384: lpBuf[(x+y*ileng)*3+1] = cpal[inBuf[x+y*ileng]].rgbGreen;
385: lpBuf[(x+y*ileng)*3+0] = cpal[inBuf[x+y*ileng]].rgbBlue;
386: }
387: GlobalFree(inBuf);
388: } else {
389: ReadFile(hdlBmp,lpBuf,dwdPixelsSize,&dwdFileSize,NULL);
390: }
391:
392: CloseHandle(hdlBmp);
393:
394:
395:
396: if(bfhBmp.bfType!='M'*256+'B'){
397:
398: GlobalFree(biBuf); GlobalFree(lpBuf);
399: MessageBox(NULL,"ファイルの種類が不正です",NULL,MB_OK);
400:
401: return FALSE;
402: }
403: return TRUE;
404: }
405:
406:
407:
408: UINT reLoadBMP(LPCTSTR lpFname)
409: {
410: UINT wx,wy; TCHAR lpStr[256];
411:
412: GlobalFree(lpBInfo);
413: GlobalFree(lpOrgBMP);
414: GlobalFree(lpBMP);
415:
416: if(LoadBMP(lpFname,lpBInfo,lpOrgBMP)){
417:
418: set_image_size(lpBInfo);
419:
420: lpBMP=(LPBYTE)GlobalAlloc(GPTR,iLength*iHeight);
421: CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight);
422:
423: GetWinPos(hAppWnd,&wx,&wy);
424: MoveWindow(hAppWnd,wx,wy,15+iWidth,iHeight+70,TRUE);
425:
426: wsprintf(lpStr,"%s %d*%d Pixel %dBit",
427: lpFname,iWidth,iHeight,lpBInfo->bmiHeader.biBitCount);
428: SetWindowText(hAppWnd,(LPSTR)lpStr);
429: return TRUE;
430: }
431: return FALSE;
432: }
433:
434:
435:
436: UINT SaveBMP(LPCTSTR lpFname,LPBITMAPINFO biBuf,LPBYTE lpBuf)
437: {
438: HANDLE hdlBmp;
439: BITMAPFILEHEADER bfhBmp;
440: LONG offset=14+40;
441: DWORD dwdFileSize=0;
442: DWORD iLen,dwdPixelsSize;
443: iLen = biBuf->bmiHeader.biWidth*3;
444: if(iLen%4) iLen += (biBuf->bmiHeader.biWidth%4);
445: dwdPixelsSize = biBuf->bmiHeader.biHeight * iLen;
446:
447: hdlBmp=CreateFile(lpFname,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
448: FILE_ATTRIBUTE_NORMAL,NULL);
449: if(hdlBmp==INVALID_HANDLE_VALUE){
450: MessageBox(NULL,"書込みに失敗しました",NULL,MB_OK);
451: return FALSE;
452: }
453:
454: bfhBmp.bfType ='M'*256+'B';
455: bfhBmp.bfSize = offset+dwdPixelsSize;
456: bfhBmp.bfReserved1 = 0;
457: bfhBmp.bfReserved2 = 0;
458: bfhBmp.bfOffBits = offset;
459:
460: WriteFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&dwdFileSize,NULL);
461:
462: WriteFile(hdlBmp,biBuf,sizeof(BITMAPINFOHEADER),&dwdFileSize,NULL);
463:
464: WriteFile(hdlBmp,lpBuf,sizeof(BYTE)*dwdPixelsSize,&dwdFileSize,NULL);
465:
466: CloseHandle(hdlBmp);
467: return TRUE;
468: }
469:
470:
471:
472: UINT SaveBMP(LPCTSTR lpFname,LPBYTE CBuf,UINT sizex,UINT sizey)
473: {
474: UINT i,x,y,ileng,add;
475: BITMAPINFO biBuf;
476: LPBYTE bmpBuf;
477:
478: biBuf.bmiHeader.biSize = 40;
479: biBuf.bmiHeader.biPlanes = 1;
480: biBuf.bmiHeader.biCompression = 0;
481: biBuf.bmiHeader.biXPelsPerMeter = 0;
482: biBuf.bmiHeader.biYPelsPerMeter = 0;
483: biBuf.bmiHeader.biClrUsed = 0;
484: biBuf.bmiHeader.biClrImportant = 0;
485: biBuf.bmiHeader.biBitCount = 24;
486: biBuf.bmiHeader.biWidth = sizex;
487: biBuf.bmiHeader.biHeight = sizey;
488: ileng = sizex*3;
489: if(ileng%4){
490: add = 4-ileng%4;
491: ileng += add;
492: } else add = 0;
493: biBuf.bmiHeader.biSizeImage = ileng*sizey;
494:
495: bmpBuf = (LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*ileng*sizey);
496: for(y=0;y<sizey;y++){
497: for(x=0;x<sizex;x++){
498: bmpBuf[x*3+(sizey-y-1)*ileng + 0] = CBuf[(x+y*sizex)*3 + 2];
499: bmpBuf[x*3+(sizey-y-1)*ileng + 1] = CBuf[(x+y*sizex)*3 + 1];
500: bmpBuf[x*3+(sizey-y-1)*ileng + 2] = CBuf[(x+y*sizex)*3 + 0];
501: }
502: for(i=0;i<add;i++)
503: bmpBuf[x*3+(sizey-y-1)*ileng + i] = 0;
504: }
505:
506: SaveBMP(lpFname,&biBuf,bmpBuf);
507:
508: GlobalFree(bmpBuf);
509: return TRUE;
510: }
511:
512:
513:
514: LPBYTE Load_template(int& sizex,int& sizey)
515: {
516: TCHAR szFn[MAX_PATH];
517: LPBYTE lpTempBMP; LPBITMAPINFO bInfo;
518:
519: if(!OpenFile(hAppWnd,szFn)) return NULL;
520:
521: if(!LoadBMP(szFn,bInfo,lpTempBMP)) return NULL;
522:
523: sizex = bInfo->bmiHeader.biWidth;
524: sizey = bInfo->bmiHeader.biHeight;
525: return lpTempBMP;
526: }