// // グラフィックで遊ぶ>モザイクをかけてみる // // 1998/ 7/ 1 宍戸 輝光 // #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(char fn[]); void moz(int,BOOL); HINSTANCE hInst; HWND hwnd; int xSize,ySize; BOOL loaded; LPBITMAPINFO lpInfo; LPBYTE lpBMP,lpBuf; 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(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "Test Window"; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); RegisterClassEx (&wndclass); hwnd = CreateWindow ("Test Window", "モザイク処理", WS_OVERLAPPEDWINDOW, 64,64, 540,480, NULL, NULL, hInstance, NULL); DragAcceptFiles(hwnd,TRUE); // ドラッグ&ドロップ受入 ShowWindow (hwnd,iCmdShow); // ウインドウを表示 UpdateWindow (hwnd); // 再描画 while (GetMessage (&msg,NULL,0,0)) { // メッセージループ TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static OPENFILENAME ofn; static char szFn[256],szFt[256]; HDROP hDrop; static HWND hwOpenB,hw2B,hw4B,hw8B,hwRB; HDC hdc; PAINTSTRUCT ps; ofn.lStructSize=sizeof(OPENFILENAME); // ファイルを開くダイアログ設定 ofn.hwndOwner=hwnd; ofn.hInstance=NULL; ofn.lpstrFilter= // フィルター "ビットマップ(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0"; ofn.lpstrCustomFilter=NULL; ofn.nMaxCustFilter=0; ofn.nFilterIndex=1; // フィルターの初期位置 ofn.lpstrFile=szFn; // ファイル名用文字列バッファ ofn.nMaxFile=255; // 文字列バッファのサイズ ofn.lpstrFileTitle=szFt; // タイトル用文字列バッファ ofn.nMaxFileTitle=255; // 文字列バッファのサイズ ofn.lpstrInitialDir=NULL; ofn.lpstrTitle="読み込むファイルを選んでください"; // タイトル ofn.Flags=OFN_FILEMUSTEXIST;// | OFN_HIDEREADONLY; ofn.nFileOffset=0; ofn.nFileExtension=0; ofn.lpstrDefExt=NULL; ofn.lCustData=0; ofn.lpfnHook=NULL; ofn.lpTemplateName=NULL; switch (iMsg) { case WM_CREATE: hwOpenB=CreateWindow("Button","Load", // ボタン作成 WS_CHILD | WS_VISIBLE,16,8,64,32,hwnd, (HMENU)0,hInst,NULL); hw2B=CreateWindow("Button","2 Pixel", WS_CHILD | WS_VISIBLE,96,8,96,32,hwnd, (HMENU)1,hInst,NULL); hw4B=CreateWindow("Button","4 Pixel", WS_CHILD | WS_VISIBLE,200,8,96,32,hwnd, (HMENU)2,hInst,NULL); hw8B=CreateWindow("Button","8 Pixel", WS_CHILD | WS_VISIBLE,304,8,96,32,hwnd, (HMENU)3,hInst,NULL); hwRB=CreateWindow("Button","Rand", // 乱数加算チェックボックス WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,408,8,96,32,hwnd, (HMENU)4,hInst,NULL); loaded=FALSE; // 読み込みフラグリセット EnableWindow(hw2B,FALSE); // モザイク処理無効 EnableWindow(hw4B,FALSE); EnableWindow(hw8B,FALSE); return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case 0: // 読み込みボタン if (!GetOpenFileName(&ofn)) // ファイルを選択 return 0; if (readBMP(szFn)) { // BMPファイル読み込み EnableWindow(hw2B,TRUE); // 条件に合えばボタン有効 EnableWindow(hw4B,TRUE); EnableWindow(hw8B,TRUE); } else { // 条件に合わなければボタン無効 EnableWindow(hw2B,FALSE); EnableWindow(hw4B,FALSE); EnableWindow(hw8B,FALSE); } return 0; case 1: // 2 Pixel moz(2,SendMessage(hwRB,BM_GETCHECK,0,0)); return 0; case 2: // 4 Pixel moz(4,SendMessage(hwRB,BM_GETCHECK,0,0)); return 0; case 3: // 8 Pixel moz(8,SendMessage(hwRB,BM_GETCHECK,0,0)); return 0; } break; case WM_DROPFILES: // ファイルがドロップされた時の処理 hDrop=(HDROP)wParam; // HDROPを取得 DragQueryFile(hDrop,0,szFn,256); // ファイル名を取得 if (readBMP(szFn)) { // BMPファイル読み込み EnableWindow(hw2B,TRUE); // 条件に合えばボタン有効 EnableWindow(hw4B,TRUE); EnableWindow(hw8B,TRUE); } else { // 条件に合わなければボタン無効 EnableWindow(hw2B,FALSE); EnableWindow(hw4B,FALSE); EnableWindow(hw8B,FALSE); } DragFinish(hDrop); // 終了処理 return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (loaded) StretchDIBits(hdc,4,48,xSize,ySize,0,0,xSize,ySize,lpBMP, lpInfo,DIB_RGB_COLORS,SRCCOPY); // DIBを画面に描画 EndPaint(hwnd,&ps); return 0; case WM_DESTROY : if (loaded) GlobalFree(lpBuf); PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(char fn[]) { // ビットマップ読み込み char str[280]; DWORD offset,dummy; HANDLE fh; if (loaded) // 以前確保したバッファを解放 GlobalFree(lpBuf); fh=CreateFile(fn,GENERIC_READ,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); // ファイルオープン lpBuf=GlobalAlloc(GPTR,GetFileSize(fh,NULL)); // バッファ確保 ReadFile(fh,lpBuf,GetFileSize(fh,NULL),&dummy,NULL); lpInfo=(LPBITMAPINFO)(lpBuf+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpBuf+10); lpBMP=lpBuf+offset; // ビットマップバッファの先頭アドレス CloseHandle(fh); if (lpBuf[0]!='B' || lpInfo->bmiHeader.biBitCount<16) { // BMPでない GlobalFree(lpBuf); loaded=FALSE; SetWindowText(hwnd,"Error!!"); return FALSE; } xSize=lpInfo->bmiHeader.biWidth; ySize=lpInfo->bmiHeader.biHeight; wsprintf(str,"%s %d*%dPixel %dBit",fn,xSize,ySize, lpInfo->bmiHeader.biBitCount); SetWindowText(hwnd,str); // ビットマップの情報表示 loaded=TRUE; // 読み込みフラグセット InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); // 再描画 // 読み込んだDIBがフルカラーかつ縦横8ピクセル単位ならTRUE return (lpInfo->bmiHeader.biBitCount==24 && (xSize % 8)==0 &&(ySize % 8)==0); } void moz(int s,BOOL c) { // モザイク処理 int i,j,k,l,rr,gg,bb; BYTE r,g,b; for (i=0;i255) rr=255; else if (rr<0) rr=0; if (gg>255) gg=255; else if (gg<0) gg=0; if (bb>255) bb=255; else if (bb<0) bb=0; r=(BYTE)rr; // ブロックの色計算 g=(BYTE)gg; b=(BYTE)bb; } else { r=(BYTE)(rr/(s*s)); // ブロックの色計算 g=(BYTE)(gg/(s*s)); b=(BYTE)(bb/(s*s)); } for (k=0;k