smooth.c
上传用户:tealon
上传日期:2007-01-18
资源大小:24k
文件大小:14k
源码类别:

图形图象

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////
  2. //Name:smooth.c
  3. //Purpose: To perform smoothing and sharpening
  4. //Author: phoenix, CS, TshingHua, Beijing, P.R.C.
  5. //Email: bjlufengjun@www.163.net or lufengjun@hotmail.com
  6. //Date:April 3, 1998
  7. //header file
  8. #include "bmp.h"
  9. #include "memory.h"
  10. #include "math.h"
  11. #include "stdio.h"
  12. //macro definition
  13. #define WIDTHBYTES(i)    ((i+31)/32*4)
  14. //function declaration
  15. int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  16. LRESULT CALLBACK MainWndProc(HWND , UINT,WPARAM, LPARAM);
  17. BOOL LoadBmpFile (HWND hWnd,char *BmpFileName);
  18. BOOL TemplateOperation(HWND hWnd, int TemplateType);
  19. BOOL MedianFilter(HWND hWnd,BOOL Hori);
  20. //global variable declaration
  21. BITMAPFILEHEADER   bf;
  22. BITMAPINFOHEADER   bi;
  23. HPALETTE           hPalette=NULL;
  24. HBITMAP            hBitmap=NULL;
  25. HGLOBAL            hImgData=NULL;
  26. DWORD              NumColors;
  27. DWORD              LineBytes;
  28. HINSTANCE          ghInst;
  29. DWORD              ImgWidth=0 , ImgHeight=0;
  30. //template array
  31. float Template_Smooth_Box[9]={1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
  32. float Template_Smooth_Gauss[9]={1.0f,2.0f,1.0f,2.0f,4.0f,2.0f,1.0f,2.0f,1.0f};
  33. float Template_Sharpen_Laplacian[9]={-1.0f,-1.0f,-1.0f,-1.0f,9.0f,-1.0f,-1.0f,-1.0f,-1.0f};
  34. ///////////////////////////////////////////////////////////
  35. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  36.     LPSTR lpszCmdLine, int nCmdShow)
  37. {
  38. MSG       msg;
  39. WNDCLASS  wndclass;
  40. HWND      hWnd;
  41. ghInst=hInstance;
  42. if ( ! hPrevInstance ){
  43. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  44. wndclass.lpfnWndProc = MainWndProc;
  45. wndclass.cbClsExtra = 0;
  46. wndclass.cbWndExtra = 0;
  47. wndclass.hInstance = hInstance;
  48. wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  49. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  50. wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  51. wndclass.lpszMenuName =  "BMPMENU";
  52. wndclass.lpszClassName = "phoenix ip system";
  53.     }
  54.     if ( ! RegisterClass (&wndclass) )
  55.     return FALSE;
  56. hWnd = CreateWindow ("phoenix ip system","Smoothing and Sharpening",
  57.  WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
  58.  CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL,
  59.  hInstance, NULL);
  60. if (!hWnd)
  61. return FALSE;
  62. ShowWindow (hWnd, SW_SHOWMAXIMIZED);
  63. UpdateWindow (hWnd);
  64. while ( GetMessage (&msg, NULL, 0, 0) ){
  65. TranslateMessage (&msg);
  66. DispatchMessage (&msg);
  67.     }
  68. return msg.wParam;
  69. }
  70. ////////////////////////////////////////////////////////////////
  71. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)
  72. {
  73.     static  HDC    hDC,hMemDC;
  74.     PAINTSTRUCT    ps;
  75.     switch (message){
  76.     case WM_PAINT:
  77. {         
  78. hDC = BeginPaint(hWnd, &ps);
  79. if (hBitmap)
  80. hMemDC = CreateCompatibleDC(hDC);
  81. if (hPalette)
  82. {           
  83. SelectPalette (hDC, hPalette, FALSE); 
  84. SelectPalette (hMemDC, hPalette, FALSE);
  85. RealizePalette (hDC);
  86. }   
  87. SelectObject(hMemDC, hBitmap); 
  88. BitBlt(hDC, 0, 0, ImgWidth,ImgHeight, hMemDC, 0, 0, SRCCOPY);
  89. DeleteDC(hMemDC);
  90. }
  91. EndPaint(hWnd, &ps);
  92. break;
  93. }
  94. case WM_DESTROY: //注意释放内存和位图,调色板句柄
  95.         if(hBitmap!=NULL)
  96.         DeleteObject(hBitmap);
  97.     
  98. if(hPalette!=NULL)                     
  99.         DeleteObject(hPalette);
  100. if(hImgData!=NULL){
  101. GlobalUnlock(hImgData);
  102. GlobalFree(hImgData);
  103. }         
  104.     PostQuitMessage (0);
  105.     return 0;
  106. case WM_COMMAND:
  107.     switch (wParam){
  108.     case IDM_LOADBMP: 
  109. //注意重新分配内存和调色板,位图句柄时,先释放原来的
  110.         if(hBitmap!=NULL){     
  111. DeleteObject(hBitmap);
  112.             hBitmap=NULL;
  113.         }
  114.         if(hPalette!=NULL){                     
  115. DeleteObject(hPalette);
  116.             hPalette=NULL;
  117.         }
  118. if(hImgData!=NULL){
  119. GlobalUnlock(hImgData);
  120. GlobalFree(hImgData);  
  121. hImgData=NULL;
  122. }         
  123. if(LoadBmpFile(hWnd,"c:\test.bmp")) //成功,则重画窗口
  124.                 InvalidateRect(hWnd,NULL,TRUE);
  125.         break;
  126. case IDM_SMOOTHING_BOX:
  127. if(hImgData!=NULL){
  128. if(TemplateOperation(hWnd,TEMPLATE_SMOOTH_BOX))
  129. InvalidateRect(hWnd,NULL,TRUE);
  130. }
  131. else
  132. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  133. break;
  134. case IDM_SMOOTHING_GAUSS:
  135. if(hImgData!=NULL){
  136. if(TemplateOperation(hWnd,TEMPLATE_SMOOTH_GAUSS))
  137. InvalidateRect(hWnd,NULL,TRUE);
  138. }
  139. else
  140. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  141. break;
  142. case IDM_SHARPENING_LAPLACIAN:
  143. if(hImgData!=NULL){
  144. if(TemplateOperation(hWnd,TEMPLATE_SHARPEN_LAPLACIAN))
  145. InvalidateRect(hWnd,NULL,TRUE);
  146. }
  147. else
  148. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  149. break;
  150. case IDM_HMEDIAN:
  151. if(hImgData!=NULL){
  152. if(MedianFilter(hWnd,TRUE))
  153. InvalidateRect(hWnd,NULL,TRUE);
  154. }
  155. else
  156. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  157. break;
  158. case IDM_VMEDIAN:
  159. if(hImgData!=NULL){
  160. if(MedianFilter(hWnd,FALSE))
  161. InvalidateRect(hWnd,NULL,TRUE);
  162. }
  163. else
  164. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  165. break;
  166. case IDM_EXIT:
  167.         SendMessage(hWnd,WM_DESTROY,0,0L);
  168.         break;
  169.     }
  170. break;                
  171.     }
  172.     return DefWindowProc (hWnd, message, wParam, lParam);
  173. }
  174. ////////////////////////////////////////////////////////////////
  175. BOOL LoadBmpFile (HWND hWnd,char *BmpFileName)
  176. {   
  177.     HFILE              hf;
  178.     LPBITMAPINFOHEADER lpImgData;
  179.     LOGPALETTE         *pPal;
  180.     LPRGBQUAD          lpRGB;
  181.     HPALETTE           hPrevPalette; 
  182.     HDC                hDc;
  183. HLOCAL             hPal;
  184. DWORD         ImgSize;
  185. DWORD              i;
  186.     if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){
  187.         MessageBox(hWnd,"File c:\test.bmp not found!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  188.         return FALSE;
  189. }
  190. _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  191. _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
  192. ImgWidth=bi.biWidth;
  193. ImgHeight=bi.biHeight;
  194. LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  195. ImgSize=(DWORD)LineBytes*bi.biHeight;
  196.     if(bi.biClrUsed!=0)
  197. NumColors=(DWORD)bi.biClrUsed;
  198. else
  199.         switch(bi.biBitCount){
  200.         case 1:
  201.              NumColors=2;
  202.              break;
  203.          case 4:
  204.              NumColors=16;
  205.              break;
  206.          case 8:
  207.              NumColors=256;
  208.              break;
  209.          case 24:
  210.              NumColors=0;
  211.              break;
  212.               default:
  213.                   MessageBox(hWnd,"Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  214.                   _lclose(hf);
  215.                   return FALSE; 
  216.         }
  217. if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
  218. +sizeof(BITMAPINFOHEADER)))
  219. {
  220.      MessageBox(hWnd,"Invalid color numbers!","Error Message" ,MB_OK|
  221.                MB_ICONEXCLAMATION);
  222. _lclose(hf);
  223. return FALSE; 
  224. }
  225. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
  226. if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
  227.      NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
  228. {
  229.      MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|
  230.                    MB_ICONEXCLAMATION);
  231.     _lclose(hf);
  232. return FALSE;
  233. }
  234.   
  235. lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
  236.     _llseek(hf,sizeof(BITMAPFILEHEADER),FILE_BEGIN);
  237. _hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
  238.            +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
  239. _lclose(hf);
  240.     if(NumColors!=0)
  241. {                    
  242.     hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
  243.     pPal =(LOGPALETTE *)LocalLock(hPal);
  244.     pPal->palNumEntries =(WORD) NumColors;
  245. pPal->palVersion    = 0x300;
  246.     lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
  247. for (i = 0; i < NumColors; i++) {
  248.       pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
  249. pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
  250. pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
  251. pPal->palPalEntry[i].peFlags=(BYTE)0;
  252. lpRGB++;
  253. }
  254. hPalette=CreatePalette(pPal);
  255. LocalUnlock(hPal);
  256. LocalFree(hPal);
  257. }
  258. hDc=GetDC(hWnd);
  259. if(hPalette){
  260.         hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
  261. RealizePalette(hDc);
  262. }
  263. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
  264. (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  265.     (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
  266. if(hPalette && hPrevPalette){
  267. SelectPalette(hDc,hPrevPalette,FALSE);
  268. RealizePalette(hDc);
  269. }
  270.  
  271. ReleaseDC(hWnd,hDc);
  272. GlobalUnlock(hImgData);
  273. return TRUE; 
  274. }
  275. ////////////////////////////////////////////////////////////////
  276. BOOL TemplateOperation(HWND hWnd, int TemplateType)
  277. {
  278. DWORD              OffBits,BufSize;
  279.     LPBITMAPINFOHEADER lpImgData;
  280. LPSTR              lpPtr;
  281. HLOCAL             hTempImgData;
  282. LPBITMAPINFOHEADER lpTempImgData;
  283. LPSTR              lpTempPtr;
  284. HDC                hDc;
  285. HFILE              hf;
  286. LONG               x,y;
  287. float              coef;
  288. float              CoefArray[9];
  289. float              TempNum;
  290. char               filename[80];
  291. switch(TemplateType){
  292. case TEMPLATE_SMOOTH_BOX:
  293. coef=(float)(1.0/9.0);
  294. memcpy(CoefArray,Template_Smooth_Box,9*sizeof(float));
  295. strcpy(filename,"c:\smbox.bmp");
  296. break;
  297. case TEMPLATE_SMOOTH_GAUSS:
  298. coef=(float)(1.0/16.0);
  299. memcpy(CoefArray,Template_Smooth_Gauss,9*sizeof(float));
  300. strcpy(filename,"c:\smgauss.bmp");
  301. break;
  302. case TEMPLATE_SHARPEN_LAPLACIAN:
  303. coef=(float)1.0;
  304. memcpy(CoefArray,Template_Sharpen_Laplacian,9*sizeof(float));
  305. strcpy(filename,"c:\shlaplac.bmp");
  306. break;
  307. }
  308. OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
  309. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  310. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  311.     {
  312.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  313.         return FALSE;
  314.     }
  315.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  316. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  317. lpPtr=(char *)lpImgData;
  318. lpTempPtr=(char *)lpTempImgData;
  319. memcpy(lpTempPtr,lpPtr,BufSize);
  320. for(y=1;y<bi.biHeight-1;y++)
  321. for(x=1;x<bi.biWidth-1;x++){
  322. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;
  323. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+x;
  324. TempNum=(float)((unsigned char)*(lpPtr+LineBytes-1))*CoefArray[0];
  325. TempNum+=(float)((unsigned char)*(lpPtr+LineBytes))*CoefArray[1];
  326. TempNum+=(float)((unsigned char)*(lpPtr+LineBytes+1))*CoefArray[2];
  327. TempNum+=(float)((unsigned char)*(lpPtr-1))*CoefArray[3];
  328. TempNum+=(float)((unsigned char)*lpPtr)*CoefArray[4];
  329. TempNum+=(float)((unsigned char)*(lpPtr+1))*CoefArray[5];
  330. TempNum+=(float)((unsigned char)*(lpPtr-LineBytes-1))*CoefArray[6];
  331. TempNum+=(float)((unsigned char)*(lpPtr-LineBytes))*CoefArray[7];
  332. TempNum+=(float)((unsigned char)*(lpPtr-LineBytes+1))*CoefArray[8];
  333. TempNum*=coef;
  334. if(TempNum>255.0) *lpTempPtr=(BYTE)255;
  335. else if(TempNum<0.0) 
  336. *lpTempPtr=(unsigned char)fabs(TempNum);
  337. else *lpTempPtr=(BYTE)TempNum;
  338. }
  339. hDc=GetDC(hWnd);
  340.     if(hBitmap!=NULL)
  341.     DeleteObject(hBitmap);
  342. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
  343. (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  344.     (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
  345. hf=_lcreat(filename,0);
  346. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  347. _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
  348. _lclose(hf);
  349.   ReleaseDC(hWnd,hDc);
  350. LocalUnlock(hTempImgData);
  351. LocalFree(hTempImgData);
  352. GlobalUnlock(hImgData);
  353. return TRUE;
  354. }
  355. ////////////////////////////////////////////////////////////////
  356. BOOL MedianFilter(HWND hWnd,BOOL Hori)
  357. {
  358. DWORD              OffBits,BufSize;
  359.     LPBITMAPINFOHEADER lpImgData;
  360. LPSTR              lpPtr;
  361. HLOCAL             hTempImgData;
  362. LPBITMAPINFOHEADER lpTempImgData;
  363. LPSTR              lpTempPtr;
  364. HDC                hDc;
  365. HFILE              hf;
  366. LONG               x,y;
  367. int                g,g1,g2,g3;
  368. OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
  369. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  370. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  371.     {
  372.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  373.         return FALSE;
  374.     }
  375.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  376. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  377. memcpy(lpTempImgData,lpImgData,BufSize);
  378. for(y=1;y<bi.biHeight-1;y++)
  379. for(x=1;x<bi.biWidth-1;x++){
  380. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;
  381. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+x;
  382. g2=(unsigned char)*(lpPtr);
  383. if(Hori){
  384. g1=(unsigned char)*(lpPtr-1);
  385. g3=(unsigned char)*(lpPtr+1);
  386. }
  387. else{
  388. g1=(unsigned char)*(lpPtr+LineBytes);
  389. g3=(unsigned char)*(lpPtr-LineBytes);
  390. }
  391. if(g1>g2){
  392. if(g2>g3) g=g2;
  393. else{
  394. if(g1>g3) g=g3;
  395. else g=g1;
  396. }
  397. }
  398. else{ //g1<=g2
  399. if(g1>g3) g=g1;
  400. else{ 
  401. if(g2>g3) g=g3;
  402. else g=g2;
  403. }
  404. }
  405. *lpTempPtr=(BYTE)g;
  406. }
  407. hDc=GetDC(hWnd);
  408.     if(hBitmap!=NULL)
  409.     DeleteObject(hBitmap);
  410. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
  411. (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  412.     (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
  413. if(Hori)
  414. hf=_lcreat("c:\hmedian.bmp",0);
  415. else
  416. hf=_lcreat("c:\vmedian.bmp",0);
  417. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  418. _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
  419. _lclose(hf);
  420.   ReleaseDC(hWnd,hDc);
  421. LocalUnlock(hTempImgData);
  422. LocalFree(hTempImgData);
  423. GlobalUnlock(hImgData);
  424. return TRUE;
  425. }