/* 明度変換によるコントラスト調整 2000/12/13 宍戸 輝光 */ #include LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL readBMP(LPCTSTR); void RGBtoYUV(); void YUVtoRGB(); void changeY(DWORD,DWORD); HINSTANCE hInst; HWND hwMain,hwMin,hwMax; LPBYTE lpDIB=NULL,lpPixel,lpYUV=NULL; LPBITMAPINFO lpbiInfo; DWORD dwWidth,dwHeight,dwLength,dwMax,dwMin; 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]; static HWND hwBtn; switch (iMsg) { case WM_CREATE: hwMin=CreateWindow("Edit",NULL,WS_CHILD | WS_VISIBLE |WS_BORDER, 8,4,96,22,hwnd,(HMENU)1,hInst,NULL); hwMax=CreateWindow("Edit",NULL,WS_CHILD | WS_VISIBLE |WS_BORDER, 116,4,96,22,hwnd,(HMENU)2,hInst,NULL); // ボタン作成 hwBtn=CreateWindow("BUTTON","実行",WS_CHILD|WS_VISIBLE, 224,4,72,28,hwnd,(HMENU)0,hInst,NULL); break; case WM_DROPFILES: /* ファイルがドロップされた時の処理 */ hDrop=(HDROP)wParam; /* HDROPを取得 */ DragQueryFile(hDrop,0,lpszFn,256); /* ファイル名を取得 */ if (readBMP(lpszFn)) /* 読みこみ成功ならYCrCb変換・ファイル作成 */ RGBtoYUV(); DragFinish(hDrop); /* 終了処理 */ InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow (hwnd); /* 再描画 */ break; case WM_COMMAND: if (LOWORD(wParam)==0) { GetWindowText(hwMin,lpszFn,256); dwMin=atol(lpszFn); GetWindowText(hwMax,lpszFn,256); dwMax=atol(lpszFn); changeY(dwMin,dwMax); YUVtoRGB(); InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow(hwnd); } return 0; case WM_PAINT: hdc=BeginPaint(hwnd,&ps); if (lpDIB!=NULL) /* ビットマップが読み込まれていれば */ StretchDIBits(hdc,4,34,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); if (lpYUV!=NULL) /* YCrCb用メモリ解放 */ GlobalFree(lpYUV); 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)); /* バッファ確保 */ ReadFile(fh,lpDIB,GetFileSize(fh,NULL),&dummy,NULL); lpbiInfo=(LPBITMAPINFO)(lpDIB+sizeof(BITMAPFILEHEADER)); offset=*(LPDWORD)(lpDIB+10); lpPixel=lpDIB+offset; /* ビットマップバッファの先頭アドレス */ CloseHandle(fh); /* 24ビットフルカラービットマップでなければ無効 */ if (lpDIB[0]!='B' || lpbiInfo->bmiHeader.biBitCount!=24) { GlobalFree(lpDIB); lpDIB=NULL; MessageBox(hwMain,"このファイルは使えません。","エラー",MB_OK); return FALSE; } /* ビットマップの大きさ保存 */ dwWidth=lpbiInfo->bmiHeader.biWidth; dwHeight=lpbiInfo->bmiHeader.biHeight; if (dwWidth % 4==0) /* バッファの1ラインの長さを計算 */ dwLength=dwWidth*3; else dwLength=dwWidth*3+(4-(dwWidth*3) % 4); SetWindowText(hwMain,lpszFn); return TRUE; } void RGBtoYUV(void) { /* YCrCb変換とYUVファイル作成 */ DWORD i,j; double r,g,b,y,u,v; DWORD dwM1=255,dwM2=0; char lpszBuf[16]; lpYUV=(LPBYTE)GlobalAlloc(GPTR,dwWidth*dwLength*3); for (i=0;i255) y=255; if (u<0) u=0; if (u>255) u=255; if (v<0) v=0; if (v>255) v=255; /* バッファに保存 */ lpYUV[j*3+i*dwWidth*3]=(BYTE)y; lpYUV[j*3+i*dwWidth*3+1]=(BYTE)u; lpYUV[j*3+i*dwWidth*3+2]=(BYTE)v; if (dwM1>y) dwM1=(DWORD)y; if (dwM2255) r=255; if (g<0) g=0; if (g>255) g=255; if (b<0) b=0; if (b>255) b=255; lpPixel[j*3+i*dwLength]=(BYTE)b; lpPixel[j*3+i*dwLength+1]=(BYTE)g; lpPixel[j*3+i*dwLength+2]=(BYTE)r; } } void changeY(DWORD dwMin,DWORD dwMax) { double lfA=255.0/(double)(dwMax-dwMin),y; DWORD i; if (lpYUV==NULL || dwMax<=dwMin) return; for (i=0;i255) y=255; lpYUV[i*3]=(BYTE)y; } }