第3章 色変換 【リスト3-1】 明暗強調 #include "myWin.h" #define XST 420 #define YST 10 #define GWIDTH 400 #define GHIGHT 400 #define RED(X) (X & 0xFF) #define GREEN(X) ((X>>8) & 0xFF) #define BLUE(X) ((X>>16) & 0xFF) static HBITMAP hBM[2];static HDC hBuff[2]; static BITMAP bM[2]; void clearBitmap(int i){//ビットマップのクリア SelectObject(hBuff[i], GetStockObject(NULL_PEN)); PatBlt(hBuff[i], 0,0,GWIDTH,GHIGHT,BLACKNESS);//黒塗り } void createBitmap(HWND hw){//ビットマップの設定 HDC hdc=GetDC(hw); for(int i=0;i<2;i++){ hBM[i]=CreateCompatibleBitmap(hdc,GWIDTH,GHIGHT); hBuff[i]=CreateCompatibleDC(hdc); SelectObject(hBuff[i], hBM[i]); } } int pixel(int i, int j){//画像1からピクセルを取り出す return GetPixel(hBuff[1], i,j); } void setPixel(int i, int j, COLORREF C){//画像0にピクセルを設定する SetPixel(hBuff[0], i,j, C); } double setValue(int V){ return (double)V/80; } void contrast(){ COLORREF C, R, G, B; for(int i=0;i255)R=255;if(G>255)G=255;if(B>255)B=255; C=RGB(R,G,B); setPixel(i,j, C); } } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ contrast(); InvalidateRect(hw,NULL,TRUE); } void procRButtonDown(HWND hw, WPARAM wp,LPARAM lp){ clearBitmap(0);//画像0をクリア InvalidateRect(hw,NULL,TRUE); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){//初期処理 createBitmap(hw);MoveWindow(hw,0,0,850,460,TRUE); hBM[1]=LoadBitmap(hInstance, TEXT("suzume"));//画像1に表示 GetObject(hBM[1],sizeof(BITMAP), &bM[1]); InvalidateRect(hw,NULL,TRUE); } void procPaint(HWND hw, WPARAM wp,LPARAM lp){//画面表示 PAINTSTRUCT ps; HDC hdc = BeginPaint(hw,&ps); SelectObject(hBuff[0],hBM[0]);SelectObject(hBuff[1],hBM[1]); BitBlt(hdc,10,YST,GWIDTH, GHIGHT, hBuff[0], 0,0,SRCCOPY); BitBlt(hdc,XST,YST,GWIDTH, GHIGHT, hBuff[1], 0,0,SRCCOPY); EndPaint(hw,&ps); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate(hw,wp,lp); return 0; case WM_LBUTTONDOWN : procLButtonDown(hw,wp,lp); return 0; case WM_RBUTTONDOWN : procRButtonDown(hw,wp,lp); return 0; case WM_PAINT : procPaint (hw,wp,lp); return 0; } return DefWindowProc(hw,msg,wp,lp); } (各RGB値の強調) void contrast(){ COLORREF C, R, G, B; for(int i=0;i255)R=255;if(G>255)G=255;if(B>255)B=255; C=RGB(R,G,B); setPixel(i,j, C); } } 【リスト3-2】 ガンマ補正 void gammaCorrection(){ COLORREF C, R, G, B;double DP=0.48; for(int i=0;i=0.5){ *CC=0xFF; *D=(RatioC[i]-0.5)/0.5;} else {*CC=0x0; *D=(0.5-RatioC[i])/0.5;} } void emphasisColor(){ COLORREF C, R, G, B, CC; double D; for(int i=0;iN) {min=i;break;} } HTotal=0; for(int i=255;i>=0;i--){//最大明度を求める HTotal+=RGBcount[i]; if(HTotal>N) {max=i;break;} } double DT=255.0/(double)(max-min); for(int i=0;i<256;i++){ if(i<=min) R_table[i]=0; //最小明度以下は0 else if(i>=max)R_table[i]=255;//最大明度以上は255 else R_table[i]=(int)(DT*(i-min));//平均化 } } (ヒストグラム表示のための関数例) void histgram(HWND hw){ countRGB(); int max=RGBcount[0]; for(int i=1;i<256;i++)if(RGBcount[i]>max) max=RGBcount[i]; HPEN hpen=CreatePen(PS_SOLID,1,0xFF); SelectObject(hBuff[0],hpen); MoveToEx(hBuff[0],10,350,NULL); LineTo(hBuff[0],10,5); LineTo(hBuff[0],265,5); LineTo(hBuff[0],265,350); LineTo(hBuff[0],10,350); DeleteObject(hpen); hpen=CreatePen(PS_SOLID,1,0xFF0000); SelectObject(hBuff[0],hpen); double DT=300/(double)max; for(int i=0;i<256;i++){ MoveToEx(hBuff[0],10+i,350,NULL); LineTo(hBuff[0],10+i,350-(int)((double)RGBcount[i]*DT)); } DeleteObject(hpen); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ //入力側のヒストグラムを表示するには以下2行を空白にする HistEqualize(); BitBlt(hBuff[1],0,0,GWIDTH, GHIGHT, hBuff[0], 0,0,SRCCOPY); clearBitmap(0); histgram(hw); InvalidateRect(hw,NULL,TRUE); }