/* 汎用的な拡大縮小−平均化による拡大縮小 2000/ 6/15 宍戸 輝光 */ #include #include #include HINSTANCE hInst; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); BOOL readBMP(LPCTSTR); void resize(double,double); LPBYTE lpDIB,lpPixel; LPBITMAPINFO lpbiInfo; DWORD dwWidth,dwHeight,dwLength; HWND hwMain,hwGo,hwRate,hwMes; int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine,int iCmdShow){ MSG msg; WNDCLASSEX wndclass; hInst=hInstance; /* プロセスのハンドルを保存 */ wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "CWindow"; wndclass.hIconSm = LoadIcon(NULL,IDI_APPLICATION); RegisterClassEx(&wndclass); /* ウインドウクラス登録 */ hwMain = CreateWindow("CWindow","平均化による拡大縮小", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,400, NULL,NULL,hInstance,NULL); ShowWindow(hwMain,iCmdShow); /* ウインドウを表示 */ UpdateWindow(hwMain); DragAcceptFiles(hwMain,TRUE); /* ドラッグ&ドロップ受入 */ while (GetMessage(&msg,NULL,0,0)) { /* メッセージループ */ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDROP hDrop; HDC hdc; PAINTSTRUCT ps; static TCHAR lpszFn[MAX_PATH+1],str[64]; DWORD dwSize; switch (iMsg) { case WM_CREATE: /* ウインドウ作成時の処理 */ hwGo=CreateWindow("Button","拡大縮小",WS_CHILD|WS_VISIBLE, 8,8,112,32,hwnd,(HMENU)0,hInst,NULL); hwRate=CreateWindow(TRACKBAR_CLASS,NULL,WS_CHILD|WS_VISIBLE, 128,8,240,32,hwnd,NULL,hInst,NULL); SendMessage(hwRate,TBM_SETRANGEMIN,1,1); SendMessage(hwRate,TBM_SETRANGEMAX,1,200); SendMessage(hwRate,TBM_SETPOS,1,50); EnableWindow(hwRate,FALSE); hwMes=CreateWindow("STATIC",NULL,WS_CHILD|WS_VISIBLE, 376,8,200,32,hwnd,NULL,hInst,NULL); return 0; case WM_COMMAND: /* コマンドメッセージ */ switch (LOWORD(wParam)) { case 0: /* 拡大縮小ボタン */ resize((double)SendMessage(hwRate,TBM_GETPOS,0,0)/100,(double)SendMessage(hwRate,TBM_GETPOS,0,0)/100); dwSize=SendMessage(hwRate,TBM_GETPOS,0,0); wsprintf(str,"%d%%-%d*%dpixel",dwSize,(DWORD)(dwWidth*((double)dwSize/100)), (DWORD)(dwHeight*((double)dwSize/100))); SetWindowText(hwMes,str); InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow (hwnd); /* 再描画 */ break; } return 0; case WM_HSCROLL: dwSize=SendMessage(hwRate,TBM_GETPOS,0,0); wsprintf(str,"%d%%-%d*%dpixel",dwSize,(DWORD)(dwWidth*((double)dwSize/100)), (DWORD)(dwHeight*((double)dwSize/100))); SetWindowText(hwMes,str); return 0; case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,lpszFn,256); /* ファイル名を取得 */ if (lstrcmpi(lpszFn+lstrlen(lpszFn)-4,".bmp")==0) /* BMP */ readBMP(lpszFn); DragFinish(hDrop); /* 終了処理 */ dwSize=SendMessage(hwRate,TBM_GETPOS,0,0); wsprintf(str,"%d%%-%d*%dpixel",dwSize,(DWORD)(dwWidth*((double)dwSize/100)), (DWORD)(dwHeight*((double)dwSize/100))); SetWindowText(hwMes,str); InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow (hwnd); /* 再描画 */ return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (lpDIB!=NULL) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,48,dwWidth,dwHeight, 0,0,dwWidth,dwHeight,lpPixel,lpbiInfo, DIB_RGB_COLORS,SRCCOPY); /* DIBを画面に描画 */ EndPaint(hwnd,&ps); return 0; case WM_DESTROY : /* 終了処理 */ if (lpDIB!=NULL) /* DIBメモリ解放 */ GlobalFree(lpDIB); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(LPCTSTR lpszFn) { /* ビットマップ読み込み */ DWORD offset,dummy; HANDLE fh; if (lpDIB!=NULL) /* 以前確保したバッファを解放 */ GlobalFree(lpDIB); fh=CreateFile(lpszFn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); /* ファイルオープン */ lpDIB=(LPBYTE)GlobalAlloc (GPTR,GetFileSize(fh,NULL)); /* DIBバッファ確保 */ ReadFile(fh,lpDIB,GetFileSize(fh,NULL),&dummy,NULL); CloseHandle(fh); lpbiInfo=(LPBITMAPINFO)(lpDIB+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpDIB+10); lpPixel=lpDIB+offset; /* ビットマップバッファの先頭アドレス */ /* 24ビットフルカラービットマップでなければ無効 */ if (lpDIB[0]!='B' || lpbiInfo->bmiHeader.biBitCount!=24) { GlobalFree(lpDIB); lpDIB=NULL; return FALSE; } /* ビットマップの大きさ保存 */ dwWidth=lpbiInfo->bmiHeader.biWidth; dwHeight=lpbiInfo->bmiHeader.biHeight; if ((dwWidth*3) % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); EnableWindow(hwRate,TRUE); SendMessage(hwRate,TBM_SETPOS,1,50); return TRUE; } void resize(double lfXRate,double lfYRate) { DWORD dwWid2,dwHei2,dwLen2,dwSX,dwEX,dwSY,dwEY,i,j,k,l; LPBYTE lpOPix; double lfR,lfG,lfB,lfSum,lfXW,lfYW; /* 作業用バッファを確保し、元画像をコピー */ lpOPix=(LPBYTE)GlobalAlloc(GPTR,dwLength*dwHeight); CopyMemory(lpOPix,lpPixel,dwLength*dwHeight); dwWid2=(DWORD)(dwWidth*lfXRate); /* 縮小後の横幅計算 */ dwHei2=(DWORD)(dwHeight*lfYRate); /* 縮小後の横幅計算 */ if ((dwWid2*3) % 4==0) /* バッファの1ラインの長さを計算 */ dwLen2=dwWid2*3; else dwLen2=dwWid2*3+(4-(dwWid2*3) % 4); /* 現在の画像を破棄し、拡大縮小後のサイズでビットマップを作り直す */ GlobalFree(lpDIB); lpDIB=(LPBYTE)GlobalAlloc(GPTR,sizeof(BITMAPINFO)+dwLen2*dwHei2); lpbiInfo=(LPBITMAPINFO)lpDIB; lpPixel=lpDIB+sizeof(BITMAPINFO); lpbiInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER); lpbiInfo->bmiHeader.biPlanes=1; lpbiInfo->bmiHeader.biBitCount=24; lpbiInfo->bmiHeader.biCompression=BI_RGB; for (i=0;ibmiHeader.biWidth=(DWORD)(dwWidth*lfXRate); dwWidth=lpbiInfo->bmiHeader.biWidth; dwLength=dwLen2; lpbiInfo->bmiHeader.biHeight=(DWORD)(dwHeight*lfYRate); dwHeight=lpbiInfo->bmiHeader.biHeight; GlobalFree(lpOPix); }