morph.c
上传用户:sales1818
上传日期:2022-03-31
资源大小:15k
文件大小:28k
源码类别:

GDI/图象编程

开发平台:

C/C++

  1. //////////////////////////////////////////////////////////////
  2. //Name:morph.c
  3. //Purpose: To perform morphological operation
  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. //owner defined stack
  13. typedef struct{
  14.   HGLOBAL hMem;
  15.      POINT *lpMyStack;
  16.   LONG  ElementsNum;
  17.   LONG  ptr;
  18.   }MYSTACK;
  19. //macro definition
  20. #define WIDTHBYTES(i)    ((i+31)/32*4)
  21. #define PI 3.1415926535
  22. #define RADIAN(angle) ((angle)*PI/180.0) //convert angle to radian
  23. //function declaration
  24. int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  25. LRESULT CALLBACK MainWndProc(HWND , UINT,WPARAM, LPARAM);
  26. BOOL LoadBmpFile (HWND hWnd,char *BmpFileName);
  27. BOOL Dilation(HWND hWnd,BOOL Hori);
  28. BOOL Erosion(HWND hWnd,BOOL Hori);
  29. BOOL MorphOpen(HWND hWnd,BOOL Hori);
  30. BOOL MorphClose(HWND hWnd,BOOL Hori);
  31. BOOL Thinning(HWND hWnd);
  32. //global variable declaration
  33. BITMAPFILEHEADER   bf;
  34. BITMAPINFOHEADER   bi;
  35. HPALETTE           hPalette=NULL;
  36. HBITMAP            hBitmap=NULL;
  37. HGLOBAL            hImgData=NULL;
  38. DWORD              NumColors;
  39. DWORD              LineBytes;
  40. HINSTANCE          ghInst;
  41. DWORD              ImgWidth=0 , ImgHeight=0;
  42. ///////////////////////////////////////////////////////////
  43. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  44.     LPSTR lpszCmdLine, int nCmdShow)
  45. {
  46. MSG       msg;
  47. WNDCLASS  wndclass;
  48. HWND      hWnd;
  49. ghInst=hInstance;
  50. if ( ! hPrevInstance ){
  51. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  52. wndclass.lpfnWndProc = MainWndProc;
  53. wndclass.cbClsExtra = 0;
  54. wndclass.cbWndExtra = 0;
  55. wndclass.hInstance = hInstance;
  56. wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  57. wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  58. wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  59. wndclass.lpszMenuName =  "BMPMENU";
  60. wndclass.lpszClassName = "phoenix ip system";
  61.     }
  62.     if ( ! RegisterClass (&wndclass) )
  63. return FALSE;
  64.  
  65. hWnd = CreateWindow ("phoenix ip system","Morphological operation",
  66.  WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
  67.  CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL,
  68.  hInstance, NULL);
  69. if (!hWnd)
  70. return FALSE;
  71. ShowWindow (hWnd, SW_SHOWMAXIMIZED);
  72. UpdateWindow (hWnd);
  73. while ( GetMessage (&msg, NULL, 0, 0) ){
  74. TranslateMessage (&msg);
  75. DispatchMessage (&msg);
  76.     }
  77. return msg.wParam;
  78. }
  79. ////////////////////////////////////////////////////////////////
  80. LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)
  81. {
  82.     static  HDC    hDC,hMemDC;
  83.     PAINTSTRUCT    ps;
  84.     switch (message){
  85.     case WM_PAINT:
  86. {         
  87. hDC = BeginPaint(hWnd, &ps);
  88. if (hBitmap)
  89. hMemDC = CreateCompatibleDC(hDC);
  90. if (hPalette)
  91. {           
  92. SelectPalette (hDC, hPalette, FALSE); 
  93. SelectPalette (hMemDC, hPalette, FALSE);
  94. RealizePalette (hDC);
  95. }   
  96. SelectObject(hMemDC, hBitmap); 
  97. BitBlt(hDC, 0, 0, ImgWidth,ImgHeight, hMemDC, 0, 0, SRCCOPY);
  98. DeleteDC(hMemDC);
  99. }
  100. EndPaint(hWnd, &ps);
  101. break;
  102. }
  103. case WM_DESTROY: //注意释放内存和位图,调色板句柄
  104.         if(hBitmap!=NULL)
  105.         DeleteObject(hBitmap);
  106.     
  107. if(hPalette!=NULL)                     
  108.         DeleteObject(hPalette);
  109. if(hImgData!=NULL){
  110. GlobalUnlock(hImgData);
  111. GlobalFree(hImgData);
  112. }         
  113.     PostQuitMessage (0);
  114.     return 0;
  115. case WM_COMMAND:
  116.     switch (wParam){
  117.     case IDM_LOADBMP: 
  118. //注意重新分配内存和调色板,位图句柄时,先释放原来的
  119.         if(hBitmap!=NULL){     
  120. DeleteObject(hBitmap);
  121.             hBitmap=NULL;
  122.         }
  123.         if(hPalette!=NULL){                     
  124. DeleteObject(hPalette);
  125.             hPalette=NULL;
  126.         }
  127. if(hImgData!=NULL){
  128. GlobalUnlock(hImgData);
  129. GlobalFree(hImgData);  
  130. hImgData=NULL;
  131. }         
  132. if(LoadBmpFile(hWnd,"c:\test.bmp")) //成功,则重画窗口
  133.                 InvalidateRect(hWnd,NULL,TRUE);
  134.         break;
  135. case IDM_HDILATION:
  136. if(hImgData!=NULL){
  137. if(Dilation(hWnd,TRUE))
  138. InvalidateRect(hWnd,NULL,TRUE);
  139. }
  140. else
  141. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  142. break;
  143. case IDM_VDILATION:
  144. if(hImgData!=NULL){
  145. if(Dilation(hWnd,FALSE))
  146. InvalidateRect(hWnd,NULL,TRUE);
  147. }
  148. else
  149. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  150. break;
  151. case IDM_HEROSION:
  152. if(hImgData!=NULL){
  153. if(Erosion(hWnd,TRUE))
  154. InvalidateRect(hWnd,NULL,TRUE);
  155. }
  156. else
  157. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  158. break;
  159. case IDM_VEROSION:
  160. if(hImgData!=NULL){
  161. if(Erosion(hWnd,FALSE))
  162. InvalidateRect(hWnd,NULL,TRUE);
  163. }
  164. else
  165. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  166. break;
  167. case IDM_HOPEN:
  168. if(hImgData!=NULL){
  169. if(MorphOpen(hWnd,TRUE))
  170. InvalidateRect(hWnd,NULL,TRUE);
  171. }
  172. else
  173. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  174. break;
  175. case IDM_VOPEN:
  176. if(hImgData!=NULL){
  177. if(MorphOpen(hWnd,FALSE))
  178. InvalidateRect(hWnd,NULL,TRUE);
  179. }
  180. else
  181. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  182. break;
  183. case IDM_HCLOSE:
  184. if(hImgData!=NULL){
  185. if(MorphClose(hWnd,TRUE))
  186. InvalidateRect(hWnd,NULL,TRUE);
  187. }
  188. else
  189. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  190. break;
  191. case IDM_VCLOSE:
  192. if(hImgData!=NULL){
  193. if(MorphClose(hWnd,FALSE))
  194. InvalidateRect(hWnd,NULL,TRUE);
  195. }
  196. else
  197. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  198. break;
  199. case IDM_THINNING:
  200. if(hImgData!=NULL){
  201. if(Thinning(hWnd))
  202. InvalidateRect(hWnd,NULL,TRUE);
  203. }
  204. else
  205. MessageBox(hWnd,"File not loaded yet!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  206. break;
  207. case IDM_EXIT:
  208.         SendMessage(hWnd,WM_DESTROY,0,0L);
  209.         break;
  210.     }
  211. break;                
  212.     }
  213.     return DefWindowProc (hWnd, message, wParam, lParam);
  214. }
  215. ////////////////////////////////////////////////////////////////
  216. BOOL LoadBmpFile (HWND hWnd,char *BmpFileName)
  217. {   
  218.     HFILE              hf;
  219.     LPBITMAPINFOHEADER lpImgData;
  220.     LOGPALETTE         *pPal;
  221.     LPRGBQUAD          lpRGB;
  222.     HPALETTE           hPrevPalette; 
  223.     HDC                hDc;
  224. HLOCAL             hPal;
  225. DWORD         ImgSize;
  226. DWORD              i;
  227.     if((hf=_lopen(BmpFileName,OF_READ))==HFILE_ERROR){
  228.         MessageBox(hWnd,"File c:\test.bmp not found!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  229.         return FALSE;
  230. }
  231. _lread(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  232. _lread(hf,(LPSTR)&bi,sizeof(BITMAPINFOHEADER));
  233. ImgWidth=bi.biWidth;
  234. ImgHeight=bi.biHeight;
  235. LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
  236. ImgSize=(DWORD)LineBytes*bi.biHeight;
  237.     if(bi.biClrUsed!=0)
  238. NumColors=(DWORD)bi.biClrUsed;
  239. else
  240.         switch(bi.biBitCount){
  241.         case 1:
  242.              NumColors=2;
  243.              break;
  244.          case 4:
  245.              NumColors=16;
  246.              break;
  247.          case 8:
  248.              NumColors=256;
  249.              break;
  250.          case 24:
  251.              NumColors=0;
  252.              break;
  253.               default:
  254.                   MessageBox(hWnd,"Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  255.                   _lclose(hf);
  256.                   return FALSE; 
  257.         }
  258. if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)
  259. +sizeof(BITMAPINFOHEADER)))
  260. {
  261.      MessageBox(hWnd,"Invalid color numbers!","Error Message" ,MB_OK|
  262.                MB_ICONEXCLAMATION);
  263. _lclose(hf);
  264. return FALSE; 
  265. }
  266. bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;
  267. if((hImgData=GlobalAlloc(GHND,(DWORD)(sizeof(BITMAPINFOHEADER)+
  268.      NumColors*sizeof(RGBQUAD)+ImgSize)))==NULL)
  269. {
  270.      MessageBox(hWnd,"Error alloc memory!","ErrorMessage",MB_OK|
  271.                    MB_ICONEXCLAMATION);
  272.     _lclose(hf);
  273. return FALSE;
  274. }
  275.   
  276. lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
  277.     _llseek(hf,sizeof(BITMAPFILEHEADER),FILE_BEGIN);
  278. _hread(hf,(char *)lpImgData,(long)sizeof(BITMAPINFOHEADER)
  279.            +(long)NumColors*sizeof(RGBQUAD)+ImgSize);
  280. _lclose(hf);
  281.     if(NumColors!=0)
  282. {                    
  283.     hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NumColors* sizeof(PALETTEENTRY));
  284.     pPal =(LOGPALETTE *)LocalLock(hPal);
  285.     pPal->palNumEntries =(WORD) NumColors;
  286. pPal->palVersion    = 0x300;
  287.     lpRGB = (LPRGBQUAD)((LPSTR)lpImgData + (DWORD)sizeof(BITMAPINFOHEADER));
  288. for (i = 0; i < NumColors; i++) {
  289.       pPal->palPalEntry[i].peRed=lpRGB->rgbRed;
  290. pPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
  291. pPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
  292. pPal->palPalEntry[i].peFlags=(BYTE)0;
  293. lpRGB++;
  294. }
  295. hPalette=CreatePalette(pPal);
  296. LocalUnlock(hPal);
  297. LocalFree(hPal);
  298. }
  299. hDc=GetDC(hWnd);
  300. if(hPalette){
  301.         hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
  302. RealizePalette(hDc);
  303. }
  304. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpImgData, (LONG)CBM_INIT,
  305. (LPSTR)lpImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  306.     (LPBITMAPINFO)lpImgData, DIB_RGB_COLORS);
  307. if(hPalette && hPrevPalette){
  308. SelectPalette(hDc,hPrevPalette,FALSE);
  309. RealizePalette(hDc);
  310. }
  311.  
  312. ReleaseDC(hWnd,hDc);
  313. GlobalUnlock(hImgData);
  314. return TRUE; 
  315. }
  316. ////////////////////////////////////////////////////////////////
  317. BOOL Erosion(HWND hWnd,BOOL Hori)
  318. {
  319. DWORD              BufSize;
  320.     LPBITMAPINFOHEADER lpImgData;
  321. LPSTR              lpPtr;
  322. HLOCAL             hTempImgData;
  323. LPBITMAPINFOHEADER lpTempImgData;
  324. LPSTR              lpTempPtr;
  325. HDC                hDc;
  326. HFILE              hf;
  327. LONG               x,y;
  328. unsigned char      num;
  329. int                i;
  330. if( NumColors!=256){
  331.      MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  332.         return FALSE;
  333.     }
  334. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  335. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  336.     {
  337.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  338.         return FALSE;
  339.     }
  340.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  341. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  342. //copy image data
  343. memcpy(lpTempImgData,lpImgData,BufSize);
  344. if(Hori)
  345. {
  346. for(y=0;y<bi.biHeight;y++){
  347. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;
  348. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  349. for(x=1;x<bi.biWidth-1;x++){
  350. num=(unsigned char)*lpPtr;
  351. if (num==0){
  352. *lpTempPtr=(unsigned char)0;
  353. for(i=0;i<3;i++){
  354. num=(unsigned char)*(lpPtr+i-1);
  355. if(num==255){
  356. *lpTempPtr=(unsigned char)255;
  357. break;
  358. }
  359. }
  360. }
  361. else *lpTempPtr=(unsigned char)255;
  362. lpPtr++;
  363. lpTempPtr++;
  364. }
  365. }
  366. }
  367. else{
  368. for(y=1;y<bi.biHeight-1;y++){
  369. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  370. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  371. for(x=0;x<bi.biWidth;x++){
  372. num=(unsigned char)*lpPtr;
  373. if (num==0){
  374. *lpTempPtr=(unsigned char)0;
  375. for(i=0;i<3;i++){
  376. num=(unsigned char)*(lpPtr+(i-1)*LineBytes);
  377. if(num==255){
  378. *lpTempPtr=(unsigned char)255;
  379. break;
  380. }
  381. }
  382. }
  383. else *lpTempPtr=(unsigned char)255;
  384. lpPtr++;
  385. lpTempPtr++;
  386. }
  387. }
  388. }
  389.     if(hBitmap!=NULL)
  390.     DeleteObject(hBitmap);
  391. hDc=GetDC(hWnd);
  392. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
  393. (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  394.     (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
  395. if(Hori)
  396. hf=_lcreat("c:\herosion.bmp",0);
  397. else
  398. hf=_lcreat("c:\verosion.bmp",0);
  399. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  400. _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
  401. _lclose(hf);
  402.   ReleaseDC(hWnd,hDc);
  403. LocalUnlock(hTempImgData);
  404. LocalFree(hTempImgData);
  405. GlobalUnlock(hImgData);
  406. return TRUE;
  407. }
  408. ////////////////////////////////////////////////////////////////
  409. BOOL Dilation(HWND hWnd,BOOL Hori)
  410. {
  411. DWORD              BufSize;
  412.     LPBITMAPINFOHEADER lpImgData;
  413. LPSTR              lpPtr;
  414. HLOCAL             hTempImgData;
  415. LPBITMAPINFOHEADER lpTempImgData;
  416. LPSTR              lpTempPtr;
  417. HDC                hDc;
  418. HFILE              hf;
  419. LONG               x,y;
  420. unsigned char      num;
  421. int                i;
  422. if( NumColors!=256){
  423.      MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  424.         return FALSE;
  425.     }
  426. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  427. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  428.     {
  429.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  430.         return FALSE;
  431.     }
  432.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  433. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  434. //copy image data
  435. memcpy(lpTempImgData,lpImgData,BufSize);
  436. if(Hori)
  437. {
  438. for(y=0;y<bi.biHeight;y++){
  439. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;
  440. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  441. for(x=1;x<bi.biWidth-1;x++){
  442. num=(unsigned char)*lpPtr;
  443. if (num==255){
  444. *lpTempPtr=(unsigned char)255;
  445. for(i=0;i<3;i++){
  446. num=(unsigned char)*(lpPtr+i-1);
  447. if(num==0){
  448. *lpTempPtr=(unsigned char)0;
  449. break;
  450. }
  451. }
  452. }
  453. else *lpTempPtr=(unsigned char)0;
  454. lpPtr++;
  455. lpTempPtr++;
  456. }
  457. }
  458. }
  459. else{
  460. for(y=1;y<bi.biHeight-1;y++){
  461. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  462. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  463. for(x=0;x<bi.biWidth;x++){
  464. num=(unsigned char)*lpPtr;
  465. if (num==255){
  466. *lpTempPtr=(unsigned char)255;
  467. for(i=0;i<3;i++){
  468. num=(unsigned char)*(lpPtr+(i-1)*LineBytes);
  469. if(num==0){
  470. *lpTempPtr=(unsigned char)0;
  471. break;
  472. }
  473. }
  474. }
  475. else *lpTempPtr=(unsigned char)0;
  476. lpPtr++;
  477. lpTempPtr++;
  478. }
  479. }
  480. }
  481.     if(hBitmap!=NULL)
  482.     DeleteObject(hBitmap);
  483. hDc=GetDC(hWnd);
  484. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
  485. (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  486.     (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
  487. if(Hori)
  488. hf=_lcreat("c:\hdilation.bmp",0);
  489. else
  490. hf=_lcreat("c:\vdilation.bmp",0);
  491. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  492. _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
  493. _lclose(hf);
  494.   ReleaseDC(hWnd,hDc);
  495. LocalUnlock(hTempImgData);
  496. LocalFree(hTempImgData);
  497. GlobalUnlock(hImgData);
  498. return TRUE;
  499. }
  500. ////////////////////////////////////////////////////////////////
  501. BOOL MorphOpen(HWND hWnd,BOOL Hori)
  502. {
  503. DWORD              BufSize;
  504.     LPBITMAPINFOHEADER lpImgData;
  505. LPSTR              lpPtr;
  506. HLOCAL             hTempImgData;
  507. LPBITMAPINFOHEADER lpTempImgData;
  508. LPSTR              lpTempPtr;
  509. HLOCAL             hTempImgData1;
  510. LPBITMAPINFOHEADER lpTempImgData1;
  511. LPSTR              lpTempPtr1;
  512. HDC                hDc;
  513. HFILE              hf;
  514. LONG               x,y;
  515. unsigned char      num;
  516. int                i;
  517. if( NumColors!=256){
  518.      MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  519.         return FALSE;
  520.     }
  521. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  522. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  523.     {
  524.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  525.         return FALSE;
  526.     }
  527. if((hTempImgData1=LocalAlloc(LHND,BufSize))==NULL)
  528.     {
  529.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  530. LocalFree(hTempImgData);
  531.         return FALSE;
  532.     }
  533. //step 1: erosion,the result is stored in lpTempImgData
  534.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  535. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  536. //copy image data
  537. memcpy(lpTempImgData,lpImgData,BufSize);
  538. if(Hori)
  539. {
  540. for(y=0;y<bi.biHeight;y++){
  541. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;
  542. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  543. for(x=1;x<bi.biWidth-1;x++){
  544. num=(unsigned char)*lpPtr;
  545. if (num==0){
  546. *lpTempPtr=(unsigned char)0;
  547. for(i=0;i<3;i++){
  548. num=(unsigned char)*(lpPtr+i-1);
  549. if(num==255){
  550. *lpTempPtr=(unsigned char)255;
  551. break;
  552. }
  553. }
  554. }
  555. else *lpTempPtr=(unsigned char)255;
  556. lpPtr++;
  557. lpTempPtr++;
  558. }
  559. }
  560. }
  561. else{
  562. for(y=1;y<bi.biHeight-1;y++){
  563. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  564. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  565. for(x=0;x<bi.biWidth;x++){
  566. num=(unsigned char)*lpPtr;
  567. if (num==0){
  568. *lpTempPtr=(unsigned char)0;
  569. for(i=0;i<3;i++){
  570. num=(unsigned char)*(lpPtr+(i-1)*LineBytes);
  571. if(num==255){
  572. *lpTempPtr=(unsigned char)255;
  573. break;
  574. }
  575. }
  576. }
  577. else *lpTempPtr=(unsigned char)255;
  578. lpPtr++;
  579. lpTempPtr++;
  580. }
  581. }
  582. }
  583. //step 2: dilation,the result is stored in lpTempImgData1
  584. //copy image data
  585. lpTempImgData1=(LPBITMAPINFOHEADER)LocalLock(hTempImgData1);
  586. //copy image data
  587. memcpy(lpTempImgData1,lpTempImgData,BufSize);
  588. if(Hori)
  589. {
  590. for(y=0;y<bi.biHeight;y++){
  591. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  592. lpTempPtr1=(char *)lpTempImgData1+(BufSize-LineBytes-y*LineBytes)+1;
  593. for(x=1;x<bi.biWidth-1;x++){
  594. num=(unsigned char)*lpTempPtr;
  595. if (num==255){
  596. *lpTempPtr1=(unsigned char)255;
  597. for(i=0;i<3;i++){
  598. num=(unsigned char)*(lpTempPtr+i-1);
  599. if(num==0){
  600. *lpTempPtr1=(unsigned char)0;
  601. break;
  602. }
  603. }
  604. }
  605. else *lpTempPtr1=(unsigned char)0;
  606. lpTempPtr++;
  607. lpTempPtr1++;
  608. }
  609. }
  610. }
  611. else{
  612. for(y=1;y<bi.biHeight-1;y++){
  613. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  614. lpTempPtr1=(char *)lpTempImgData1+(BufSize-LineBytes-y*LineBytes);
  615. for(x=0;x<bi.biWidth;x++){
  616. num=(unsigned char)*lpTempPtr;
  617. if (num==255){
  618. *lpTempPtr1=(unsigned char)255;
  619. for(i=0;i<3;i++){
  620. num=(unsigned char)*(lpTempPtr+(i-1)*LineBytes);
  621. if(num==0){
  622. *lpTempPtr1=(unsigned char)0;
  623. break;
  624. }
  625. }
  626. }
  627. else *lpTempPtr1=(unsigned char)0;
  628. lpTempPtr++;
  629. lpTempPtr1++;
  630. }
  631. }
  632. }
  633.     if(hBitmap!=NULL)
  634.     DeleteObject(hBitmap);
  635. hDc=GetDC(hWnd);
  636. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData1, (LONG)CBM_INIT,
  637. (LPSTR)lpTempImgData1+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  638.     (LPBITMAPINFO)lpTempImgData1, DIB_RGB_COLORS);
  639. if(Hori)
  640. hf=_lcreat("c:\hmopen.bmp",0);
  641. else
  642. hf=_lcreat("c:\vmopen.bmp",0);
  643. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  644. _lwrite(hf,(LPSTR)lpTempImgData1,BufSize);
  645. _lclose(hf);
  646.   ReleaseDC(hWnd,hDc);
  647. LocalUnlock(hTempImgData);
  648. LocalFree(hTempImgData);
  649. LocalUnlock(hTempImgData1);
  650. LocalFree(hTempImgData1);
  651. GlobalUnlock(hImgData);
  652. return TRUE;
  653. }
  654. ////////////////////////////////////////////////////////////////
  655. BOOL MorphClose(HWND hWnd,BOOL Hori)
  656. {
  657. DWORD              BufSize;
  658.     LPBITMAPINFOHEADER lpImgData;
  659. LPSTR              lpPtr;
  660. HLOCAL             hTempImgData;
  661. LPBITMAPINFOHEADER lpTempImgData;
  662. LPSTR              lpTempPtr;
  663. HLOCAL             hTempImgData1;
  664. LPBITMAPINFOHEADER lpTempImgData1;
  665. LPSTR              lpTempPtr1;
  666. HDC                hDc;
  667. HFILE              hf;
  668. LONG               x,y;
  669. unsigned char      num;
  670. int                i;
  671. if( NumColors!=256){
  672.      MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  673.         return FALSE;
  674.     }
  675. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  676. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  677.     {
  678.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  679.         return FALSE;
  680.     }
  681. if((hTempImgData1=LocalAlloc(LHND,BufSize))==NULL)
  682.     {
  683.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  684. LocalFree(hTempImgData);
  685.         return FALSE;
  686.     }
  687. //step 1: dilation,the result is stored in lpTempImgData
  688.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  689. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  690. //copy image data
  691. memcpy(lpTempImgData,lpImgData,BufSize);
  692. if(Hori)
  693. {
  694. for(y=0;y<bi.biHeight;y++){
  695. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+1;
  696. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  697. for(x=1;x<bi.biWidth-1;x++){
  698. num=(unsigned char)*lpPtr;
  699. if (num==255){
  700. *lpTempPtr=(unsigned char)255;
  701. for(i=0;i<3;i++){
  702. num=(unsigned char)*(lpPtr+i-1);
  703. if(num==0){
  704. *lpTempPtr=(unsigned char)0;
  705. break;
  706. }
  707. }
  708. }
  709. else *lpTempPtr=(unsigned char)0;
  710. lpPtr++;
  711. lpTempPtr++;
  712. }
  713. }
  714. }
  715. else{
  716. for(y=1;y<bi.biHeight-1;y++){
  717. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  718. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  719. for(x=0;x<bi.biWidth;x++){
  720. num=(unsigned char)*lpPtr;
  721. if (num==255){
  722. *lpTempPtr=(unsigned char)255;
  723. for(i=0;i<3;i++){
  724. num=(unsigned char)*(lpPtr+(i-1)*LineBytes);
  725. if(num==0){
  726. *lpTempPtr=(unsigned char)0;
  727. break;
  728. }
  729. }
  730. }
  731. else *lpTempPtr=(unsigned char)0;
  732. lpPtr++;
  733. lpTempPtr++;
  734. }
  735. }
  736. }
  737. //step 2: erosion,the result is stored in lpTempImgData1
  738. //copy image data
  739. lpTempImgData1=(LPBITMAPINFOHEADER)LocalLock(hTempImgData1);
  740. //copy image data
  741. memcpy(lpTempImgData1,lpTempImgData,BufSize);
  742. if(Hori)
  743. {
  744. for(y=0;y<bi.biHeight;y++){
  745. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+1;
  746. lpTempPtr1=(char *)lpTempImgData1+(BufSize-LineBytes-y*LineBytes)+1;
  747. for(x=1;x<bi.biWidth-1;x++){
  748. num=(unsigned char)*lpTempPtr;
  749. if (num==0){
  750. *lpTempPtr1=(unsigned char)0;
  751. for(i=0;i<3;i++){
  752. num=(unsigned char)*(lpTempPtr+i-1);
  753. if(num==255){
  754. *lpTempPtr1=(unsigned char)255;
  755. break;
  756. }
  757. }
  758. }
  759. else *lpTempPtr1=(unsigned char)255;
  760. lpTempPtr++;
  761. lpTempPtr1++;
  762. }
  763. }
  764. }
  765. else{
  766. for(y=1;y<bi.biHeight-1;y++){
  767. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  768. lpTempPtr1=(char *)lpTempImgData1+(BufSize-LineBytes-y*LineBytes);
  769. for(x=0;x<bi.biWidth;x++){
  770. num=(unsigned char)*lpTempPtr;
  771. if (num==0){
  772. *lpTempPtr1=(unsigned char)0;
  773. for(i=0;i<3;i++){
  774. num=(unsigned char)*(lpTempPtr+(i-1)*LineBytes);
  775. if(num==255){
  776. *lpTempPtr1=(unsigned char)255;
  777. break;
  778. }
  779. }
  780. }
  781. else *lpTempPtr1=(unsigned char)255;
  782. lpTempPtr++;
  783. lpTempPtr1++;
  784. }
  785. }
  786. }
  787.     if(hBitmap!=NULL)
  788.     DeleteObject(hBitmap);
  789. hDc=GetDC(hWnd);
  790. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData1, (LONG)CBM_INIT,
  791. (LPSTR)lpTempImgData1+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  792.     (LPBITMAPINFO)lpTempImgData1, DIB_RGB_COLORS);
  793. if(Hori)
  794. hf=_lcreat("c:\hmclose.bmp",0);
  795. else
  796. hf=_lcreat("c:\vmclose.bmp",0);
  797. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  798. _lwrite(hf,(LPSTR)lpTempImgData1,BufSize);
  799. _lclose(hf);
  800.   ReleaseDC(hWnd,hDc);
  801. LocalUnlock(hTempImgData);
  802. LocalFree(hTempImgData);
  803. LocalUnlock(hTempImgData1);
  804. LocalFree(hTempImgData1);
  805. GlobalUnlock(hImgData);
  806. return TRUE;
  807. }
  808. ////////////////////////////////////////////////////////////////
  809. BOOL Thinning(HWND hWnd)
  810. {
  811. DWORD              BufSize;
  812.     LPBITMAPINFOHEADER lpImgData;
  813. LPSTR              lpPtr;
  814. HLOCAL             hTempImgData;
  815. LPBITMAPINFOHEADER lpTempImgData;
  816. LPSTR              lpTempPtr;
  817. HDC                hDc;
  818. HFILE              hf;
  819. LONG               x,y;
  820. int        num;
  821. BOOL               Finished;
  822. int                nw,n,ne,w,e,sw,s,se;
  823. static int erasetable[256]={
  824. 0,0,1,1,0,0,1,1,
  825. 1,1,0,1,1,1,0,1,
  826. 1,1,0,0,1,1,1,1,
  827. 0,0,0,0,0,0,0,1,
  828. 0,0,1,1,0,0,1,1,
  829. 1,1,0,1,1,1,0,1,
  830. 1,1,0,0,1,1,1,1,
  831. 0,0,0,0,0,0,0,1,
  832. 1,1,0,0,1,1,0,0,
  833. 0,0,0,0,0,0,0,0,
  834. 0,0,0,0,0,0,0,0,
  835. 0,0,0,0,0,0,0,0,
  836. 1,1,0,0,1,1,0,0,
  837. 1,1,0,1,1,1,0,1,
  838. 0,0,0,0,0,0,0,0,
  839. 0,0,0,0,0,0,0,0,
  840. 0,0,1,1,0,0,1,1,
  841. 1,1,0,1,1,1,0,1,
  842. 1,1,0,0,1,1,1,1,
  843. 0,0,0,0,0,0,0,1,
  844. 0,0,1,1,0,0,1,1,
  845. 1,1,0,1,1,1,0,1,
  846. 1,1,0,0,1,1,1,1,
  847. 0,0,0,0,0,0,0,0,
  848. 1,1,0,0,1,1,0,0,
  849. 0,0,0,0,0,0,0,0,
  850. 1,1,0,0,1,1,1,1,
  851. 0,0,0,0,0,0,0,0,
  852. 1,1,0,0,1,1,0,0,
  853. 1,1,0,1,1,1,0,0,
  854. 1,1,0,0,1,1,1,0,
  855. 1,1,0,0,1,0,0,0
  856.   };
  857. if( NumColors!=256){
  858.      MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  859.         return FALSE;
  860.     }
  861. BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
  862. if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
  863.     {
  864.      MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
  865.         return FALSE;
  866.     }
  867.     lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);    
  868. lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
  869. //copy image data
  870. memcpy(lpTempImgData,lpImgData,BufSize);
  871. Finished=FALSE;
  872.     while(!Finished){
  873.      Finished=TRUE;
  874. for (y=1;y<bi.biHeight-1;y++){ 
  875. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  876. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  877. x=1; 
  878. while(x<bi.biWidth-1){
  879. if(*(lpPtr+x)==0){
  880. w=(unsigned char)*(lpPtr+x-1);
  881. e=(unsigned char)*(lpPtr+x+1);
  882. if( (w==255)|| (e==255)){
  883. nw=(unsigned char)*(lpPtr+x+LineBytes-1);
  884. n=(unsigned char)*(lpPtr+x+LineBytes);
  885. ne=(unsigned char)*(lpPtr+x+LineBytes+1);
  886. sw=(unsigned char)*(lpPtr+x-LineBytes-1);
  887. s=(unsigned char)*(lpPtr+x-LineBytes);
  888. se=(unsigned char)*(lpPtr+x-LineBytes+1);
  889. num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
  890. if(erasetable[num]==1){
  891. *(lpPtr+x)=(BYTE)255;
  892. *(lpTempPtr+x)=(BYTE)255;
  893. Finished=FALSE;
  894. x++;
  895. }
  896. }
  897. }
  898. x++;
  899. }
  900. }
  901. for (x=1;x<bi.biWidth-1;x++){ 
  902. y=1;
  903. while(y<bi.biHeight-1){
  904. lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
  905. lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes-y*LineBytes);
  906. if(*(lpPtr+x)==0){
  907. n=(unsigned char)*(lpPtr+x+LineBytes);
  908. s=(unsigned char)*(lpPtr+x-LineBytes);
  909. if( (n==255)|| (s==255)){
  910. nw=(unsigned char)*(lpPtr+x+LineBytes-1);
  911. ne=(unsigned char)*(lpPtr+x+LineBytes+1);
  912. w=(unsigned char)*(lpPtr+x-1);
  913. e=(unsigned char)*(lpPtr+x+1);
  914. sw=(unsigned char)*(lpPtr+x-LineBytes-1);
  915. se=(unsigned char)*(lpPtr+x-LineBytes+1);
  916. num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
  917. if(erasetable[num]==1){
  918. *(lpPtr+x)=(BYTE)255;
  919. *(lpTempPtr+x)=(BYTE)255;
  920. Finished=FALSE;
  921. y++;
  922. }
  923. }
  924. }
  925. y++;
  926. }
  927. }
  928.     if(hBitmap!=NULL)
  929.     DeleteObject(hBitmap);
  930. hDc=GetDC(hWnd);
  931. hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData, (LONG)CBM_INIT,
  932. (LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +NumColors*sizeof(RGBQUAD),
  933.     (LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
  934. hf=_lcreat("c:\thinning.bmp",0);
  935. _lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER)); 
  936. _lwrite(hf,(LPSTR)lpTempImgData,BufSize);
  937. _lclose(hf);
  938.   ReleaseDC(hWnd,hDc);
  939. LocalUnlock(hTempImgData);
  940. LocalFree(hTempImgData);
  941. GlobalUnlock(hImgData);
  942. return TRUE;
  943. }