#include "myWin.h" #include "stdio.h" #include "math.h" #define swap(type, X,Y) do{type T; T=X;X=Y; Y=T;}while(0) static HDC hBuff; static HBITMAP hBM; static int X, Y ;static int XDT[5], YDT[5]; int IMS=0;double MAT[5][6]; void clearBitmap(){//ビットマップのクリア SelectObject(hBuff,GetStockObject(NULL_PEN)); PatBlt(hBuff,0,0,1000,600,WHITENESS); } int matSolve(){//行列式を解いて多項式の係数を求める int N=5, N2=N+1; for(int k=0;k<N;k++){ if(fabs(MAT[k][k])<0.00001) return true; double S=1/MAT[k][k]; for(int j=k+1;j<N2;j++) MAT[k][j]*=S; for(int i=0;i<N;i++) if(i!=k){ S=MAT[i][k]; for(int j=k+1;j<N2;j++)MAT[i][j] -= S*MAT[k][j]; } } return false; } void dblToStr(double d, TCHAR str[]){//doubleを文字列に char tmp[256]; sprintf(tmp," %15.4E", d);int i; for(i=0; tmp[i];i++) str[i]=tmp[i]; str[i]=0; } void setData(){ for(int i=0;i<4;i++)for(int j=4;j>i;j--)//X座標の小さい順にソート if(XDT[j-1]>XDT[j]){ swap(int, XDT[j-1],XDT[j]);swap(int, YDT[j-1],YDT[j]); } for(int i=0; i<5;i++) for(int j=0; j<5;j++){//左辺行列 MAT[i][j]=0; for(int k=0; k<5; k++) MAT[i][j]+=pow(XDT[k],(double)(i+j)); } for(int i=0; i<5;i++){//右辺ベクトル MAT[i][5]=0; for(int k=0; k<5; k++) MAT[i][5]+=pow(XDT[k],(double)i)*YDT[k]; } matSolve();//上記行列式を解いて係数を設定する。 } void initData(){//初期値設定 for(int i=0; i<5;i++){ XDT[i] = YDT[i] = 64*i;} setData(); matSolve(); } int setValue(double X){//カラートーン値を求める関数 double A=0; for(int i=4;i>=0;i--)A = A*X+MAT[i][5]; if(A<0)A=0; if(A>255)A=255; return (int)A; } void drawFig(HWND hw){ clearBitmap(); HPEN pen = CreatePen(PS_SOLID,1,0);SelectObject(hBuff,pen); Rectangle(hBuff,10,10,266,266); MoveToEx(hBuff,10,265,NULL); for(int k=1;k<256; k++) LineTo(hBuff,k+10,265-(int)setValue((double)k)); for(int j=1;j<=3;j++){ int k=XDT[j], A=setValue(XDT[j]); Rectangle(hBuff,k+7,262-(int)A, k+13,268-(int)A); } // トーンカーブの係数を表示する処理(アプリに組み込むときはいらない) HFONT hF=CreateFont(16,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, FIXED_PITCH|FF_MODERN,NULL); SelectObject(hBuff,hF); TCHAR str[1024]; lstrcpy(str,TEXT("多項式の係数")); TextOut(hBuff,10,270,str,lstrlen(str)); dblToStr(MAT[0][5],str); TextOut(hBuff,120,270,str,lstrlen(str)); dblToStr(MAT[1][5],str); TextOut(hBuff,120,290,str,lstrlen(str)); dblToStr(MAT[2][5],str); TextOut(hBuff,120,310,str,lstrlen(str)); dblToStr(MAT[3][5],str); TextOut(hBuff,120,330,str,lstrlen(str)); dblToStr(MAT[4][5],str); TextOut(hBuff,120,350,str,lstrlen(str)); DeleteObject(hF); // トーンカーブの係数を表示する処理 ここまで DeleteObject(pen); InvalidateRect(hw,NULL,TRUE); } void viewChange(HWND hw, int X, int Y){//座標値の変更 if(Y>255 || Y<0 || X>255 || X<0) {IMS = 0;return;} int MinDT = 9999999, ID=0; for(int i=1;i<=3; i++){ int DX = X-XDT[i],DY=Y-YDT[i], RR=DX*DX+DY*DY; if(RR<MinDT){ MinDT=RR; ID=i;} } if(MinDT<16){ IMS=ID; XDT[IMS]=X; YDT[IMS]=Y;setData(); drawFig(hw); } } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ initData();MoveWindow(hw,0,0,300,420,TRUE); SetWindowText(hw,TEXT("トーンカーブ用係数計算")); HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,1000,600); hBuff=CreateCompatibleDC(hdc); SelectObject(hBuff,hBM); viewChange(hw,127,127); drawFig(hw); ReleaseDC(hw,hdc); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ X=LOWORD(lp)-10; Y=265-HIWORD(lp); viewChange(hw,X,Y); } void procLButtonUp(HWND hw, WPARAM wp,LPARAM lp){ IMS=0;} void procMouseMove(HWND hw, WPARAM wp,LPARAM lp){ if(GetKeyState(VK_LBUTTON)<0 && IMS!=0){ X=LOWORD(lp)-10; Y=265-HIWORD(lp); viewChange(hw,X, Y); } } void procPaint(HWND hw,WPARAM wp,LPARAM lp){ PAINTSTRUCT ps; HDC hdc=BeginPaint(hw,&ps); BitBlt(hdc,0,0,1000,600,hBuff,0,0,SRCCOPY); EndPaint(hw,&ps); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : DeleteDC(hBuff);DeleteObject(hBM); PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate (hw,wp,lp); return 0; case WM_LBUTTONDOWN: procLButtonDown(hw,wp,lp); return 0; case WM_LBUTTONUP : procLButtonUp (hw,wp,lp); return 0; case WM_MOUSEMOVE : procMouseMove (hw,wp,lp); return 0; case WM_PAINT : procPaint (hw,wp,lp); return 0; } return DefWindowProc(hw,msg,wp,lp); }