/*    色成分差の拡大 2003/ 5/ 6 宍戸 輝光 */ #include LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); BOOL readBMP(LPCTSTR); void func(); HINSTANCE hInst; HWND hwMain; LPBYTE lpDIB = NULL; LPBITMAPINFO lpbiInfo; LPDWORD lpPixel; int iWidth, iHeight; int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine,int iCmdShow){ MSG msg; WNDCLASS wndclass ; hInst=hInstance; /* プロセスのハンドルを保存 */ 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 = "CWindow"; RegisterClass(&wndclass); hwMain = CreateWindow("CWindow", "色成分差の拡大", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 560, 480, NULL, NULL, hInstance, NULL); DragAcceptFiles(hwMain, TRUE); /* ドラッグ&ドロップ受入 */ ShowWindow(hwMain, iCmdShow); /* ウインドウを表示 */ UpdateWindow(hwMain); /* 再描画 */ 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; TCHAR lpszFn[MAX_PATH + 1], lpszTmp[64]; static HWND hwBtn; int x, y, r, g, b; switch (iMsg) { case WM_CREATE: /* ボタン作成 */ hwBtn = CreateWindow("BUTTON", "実行", WS_CHILD|WS_VISIBLE, 224, 4, 72, 28, hwnd, (HMENU)0, hInst, NULL); EnableWindow(hwBtn, FALSE); return 0; case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop = (HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop, 0, lpszFn, 256); /* ファイル名を取得 */ /* BMP読み込み */ if (readBMP(lpszFn)) { EnableWindow(hwBtn, TRUE); } DragFinish(hDrop); /* 終了処理 */ /* ウインドウを再描画 */ InvalidateRgn(hwnd, NULL, TRUE); UpdateWindow (hwnd); return 0; case WM_MOUSEMOVE: /* マウスカーソルの座標取得 */ x = LOWORD(lParam) - 4; y = iHeight - (HIWORD(lParam) - 34); if (lpDIB == NULL || x < 0 || x >= iWidth || y >= iHeight || y < 0) { return 0; } /* ピクセルのRGB成分算出 */ r = (lpPixel[x + y * iWidth] & 0x00ff0000) >> 16; g = (lpPixel[x + y * iWidth] & 0x0000ff00) >> 8; b = lpPixel[x + y * iWidth] & 0x000000ff; /* ウインドウタイトルに成分表示 */ wsprintf(lpszTmp, "(%d,%d):%d,%d,%d", x, y, r, g, b); SetWindowText(hwMain, lpszTmp); return 0; case WM_COMMAND: if (LOWORD(wParam) == 0 && lpDIB != NULL) { /* 実行ボタン */ /* 色差拡大処理実行 */ func(); /* ウインドウを再描画 */ InvalidateRgn(hwnd, NULL, FALSE); UpdateWindow(hwnd); } return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (lpDIB != NULL) { /* ビットマップが読み込まれていれば */ StretchDIBits(hdc, 4, 34, iWidth, iHeight, 0, 0, iWidth, iHeight, lpPixel, lpbiInfo, DIB_RGB_COLORS, SRCCOPY); /* DIBを画面に描画 */ } EndPaint(hwnd, &ps); return 0; case WM_DESTROY : if (lpDIB != NULL) { /* DIB用メモリ解放 */ HeapFree(GetProcessHeap(), 0, lpDIB); } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; } BOOL readBMP(LPCTSTR lpszFn) { /* ビットマップ読み込み */ DWORD offset, dummy; LPBYTE lpBuf, lpPix; LPBITMAPINFO lpWrkBM; HANDLE fh; int i, j, iLength; fh = CreateFile(lpszFn, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); /* ファイルオープン */ /* ファイル読み込みバッファ確保 */ lpBuf = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, GetFileSize(fh, NULL)); ReadFile(fh, lpBuf, GetFileSize(fh, NULL), &dummy, NULL); lpWrkBM = (LPBITMAPINFO)(lpBuf + sizeof(BITMAPFILEHEADER)); offset = *(LPDWORD)(lpBuf + 10); lpPix = lpBuf + offset; /* ビットマップバッファの先頭アドレス */ CloseHandle(fh); /* 24ビットフルカラービットマップでなければ無効 */ if (lpBuf[0] != 'B' || lpWrkBM->bmiHeader.biBitCount != 24) { HeapFree(GetProcessHeap(), 0, lpBuf); MessageBox(hwMain, "このファイルは使えません。", "エラー", MB_OK); return FALSE; } /* ビットマップの大きさ保存 */ iWidth = lpWrkBM->bmiHeader.biWidth; iHeight = lpWrkBM->bmiHeader.biHeight; if (iWidth % 4 == 0) { /* バッファの1ラインの長さを計算 */ iLength = iWidth * 3; } else { iLength = iWidth * 3 + (4 - (iWidth * 3) % 4); } if (lpDIB != NULL) { /* 以前確保したバッファを解放 */ HeapFree(GetProcessHeap(), 0, lpDIB); } lpDIB = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFO) + iLength * iHeight * 4); lpbiInfo = (LPBITMAPINFO)lpDIB; lpPixel = (LPDWORD)(lpDIB + sizeof(BITMAPINFO)); lpbiInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiInfo->bmiHeader.biWidth = iWidth; lpbiInfo->bmiHeader.biHeight = iHeight; lpbiInfo->bmiHeader.biPlanes = 1; lpbiInfo->bmiHeader.biBitCount = 32; lpbiInfo->bmiHeader.biCompression = BI_RGB; /* BMP内のピクセルを32ビット化してコピー */ for (i = 0;i < iHeight;i++) for (j = 0;j < iWidth; j++) CopyMemory(lpPixel + j + i * iWidth, lpPix + j * 3 + i * iLength, 3); HeapFree(GetProcessHeap(), 0, lpBuf); return TRUE; } void func() { /* 指定ピクセルをぼかす */ int i, j, iAvR, iAvG, iAvB, iPixR, iPixG, iPixB, n; LPDWORD lpWrk; /* 処理前画像保存用バッファ確保 */ lpWrk = (LPDWORD)HeapAlloc(GetProcessHeap(), 0, iWidth * iHeight * 4); /* 処理前の画像をバッファにコピー */ CopyMemory(lpWrk, lpPixel, iWidth * iHeight *4); for (i = 0;i < iHeight;i++) { for (j = 0;j < iWidth;j++) { iAvR = 0; iAvG = 0; iAvB = 0; n = 0; if (j > 0) { /* 一つ左のピクセルの成分 */ iAvR += (lpWrk[j - 1 + i * iWidth] & 0x00ff0000) >> 16; iAvG += (lpWrk[j - 1 + i * iWidth] & 0x0000ff00) >> 8; iAvB += lpWrk[j - 1 + i * iWidth] & 0x000000ff; n++; } if (i > 0) { /* 一つ下のピクセルの成分 */ iAvR += (lpWrk[j + (i - 1) * iWidth] & 0x00ff0000) >> 16; iAvG += (lpWrk[j + (i - 1) * iWidth] & 0x0000ff00) >> 8; iAvB += lpWrk[j + (i - 1) * iWidth] & 0x000000ff; n++; } if (j < iWidth - 1) {/* 一つ右のピクセルの成分 */ iAvR += (lpWrk[j + 1 + i * iWidth] & 0x00ff0000) >> 16; iAvG += (lpWrk[j + 1 + i * iWidth] & 0x0000ff00) >> 8; iAvB += lpWrk[j + 1 + i * iWidth] & 0x000000ff; n++; } if (i < iHeight - 1) { /* 一つ上のピクセルの成分 */ iAvR += (lpWrk[j + (i + 1) * iWidth] & 0x00ff0000) >> 16; iAvG += (lpWrk[j + (i + 1) * iWidth] & 0x0000ff00) >> 8; iAvB += lpWrk[j + (i + 1) * iWidth] & 0x000000ff; n++; } /* 周辺ピクセルの色成分の平均計算 */ iAvR = (int)(iAvR / n); iAvG = (int)(iAvG / n); iAvB = (int)(iAvB / n); /* 処理対象ピクセルの色成分計算 */ iPixR = (lpWrk[j + i * iWidth] & 0x00ff0000) >> 16; iPixG = (lpWrk[j + i * iWidth] & 0x0000ff00) >> 8; iPixB = lpWrk[j + i * iWidth] & 0x000000ff; /* 処理対象ピクセルと周辺ピクセルの色成分差拡大 */ iPixR += (iPixR - iAvR); iPixG += (iPixG - iAvG); iPixB += (iPixB - iAvB); if (iPixR < 0) { iPixR = 0; } if (iPixR > 255) { iPixR = 255; } if (iPixG < 0) { iPixG = 0; } if (iPixG > 255) { iPixG = 255; } if (iPixB < 0) { iPixB = 0; } if (iPixB > 255) { iPixB = 255; } /* 処理対象ピクセルの色成分設定 */ lpPixel[j + i * iWidth] = (iPixR << 16) + (iPixG << 8) + iPixB; } } /* バッファ解放 */ HeapFree(GetProcessHeap(), 0, lpWrk); }