ImgProcess.cpp
上传用户:gzboli
上传日期:2013-04-10
资源大小:471k
文件大小:44k
源码类别:

图片显示

开发平台:

Visual C++

  1. // ImgProcess.cpp: implementation of the CImgProcess class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "QuickImage.h"
  6. #include "ImgProcess.h"
  7. #include "MathEx.h"
  8. #include <math.h>
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. // The following kernel definitions are for convolution filtering.
  18. // Kernel entries are specified with a divisor to get around the
  19. // requirement for floating point numbers in the low pass filters. 
  20. KERNEL HP1 = {                    // HP filter #1
  21. {-1, -1, -1,
  22. -1,  9, -1,
  23. -1, -1, -1},
  24. 1                             // Divisor = 1
  25. };
  26. KERNEL HP2 = {                    // HP filter #2
  27. { 0, -1,  0,
  28. -1,  5, -1,
  29. 0, -1,  0},
  30. 1                             // Divisor = 1
  31. };
  32. KERNEL HP3 = {                    // HP filter #3
  33. { 1, -2,  1,
  34. -2,  5, -2,
  35. 1, -2,  1},
  36. 1                             // Divisor = 1
  37. };
  38. KERNEL LP1 = {                    // LP filter #1
  39. { 1,  1,  1,
  40. 1,  1,  1,
  41. 1,  1,  1},
  42. 9                             // Divisor = 9
  43. };
  44. KERNEL LP2 = {                    // LP filter #2
  45. { 1,  1,  1,
  46. 1,  2,  1,
  47. 1,  1,  1},
  48. 10                            // Divisor = 10
  49. };
  50. KERNEL LP3 = {                    // LP filter #3
  51. { 1,  2,  1,
  52. 2,  4,  2,
  53. 1,  2,  1},
  54. 16                            // Divisor = 16
  55. };
  56. KERNEL VertEdge = {              // Vertical edge
  57. { 0,  0,  0,
  58. -1, 1,  0,
  59. 0,  0,  0},
  60. 1                             // Divisor = 1
  61. };
  62. KERNEL HorzEdge = {              // Horizontal edge
  63. { 0,  -1,  0,
  64. 0,  1,  0,
  65. 0,  0,  0},
  66. 1                             // Divisor = 1
  67. };
  68. KERNEL VertHorzEdge = {           // Vertical Horizontal edge
  69. { -1, 0,  0,
  70. 0,  1,  0,
  71. 0,  0,  0},
  72. 1                             // Divisor = 1
  73. };
  74. KERNEL EdgeNorth = {              // North gradient
  75. { 1,  1,  1,
  76. 1, -2,  1,
  77. -1, -1, -1},
  78. 1                             // Divisor = 1
  79. };
  80. KERNEL EdgeNorthEast = {          // North East gradient
  81. { 1,  1,  1,
  82. -1, -2,  1,
  83. -1, -1,  1},
  84. 1                             // Divisor = 1
  85. };
  86. KERNEL EdgeEast = {               // East gradient
  87. {-1,  1,  1,
  88. -1, -2,  1,
  89. -1,  1,  1},
  90. 1                             // Divisor = 1
  91. };
  92. KERNEL EdgeSouthEast = {          // South East gradient
  93. {-1, -1,  1,
  94. -1, -2,  1,
  95. 1,  1,  1},
  96. 1                             // Divisor = 1
  97. };
  98. KERNEL EdgeSouth = {              // South gadient
  99. {-1, -1, -1,
  100. 1, -2,  1,
  101. 1,  1,  1},
  102. 1                             // Divisor = 1
  103. };
  104. KERNEL EdgeSouthWest = {          // South West gradient
  105. { 1, -1, -1,
  106. 1, -2, -1,
  107. 1,  1,  1},
  108. 1                             // Divisor = 1
  109. };
  110. KERNEL EdgeWest = {               // West gradient
  111. { 1,  1, -1,
  112. 1, -2, -1,
  113. 1,  1, -1},
  114. 1                             // Divisor = 1
  115. };
  116. KERNEL EdgeNorthWest = {          // North West gradient
  117. { 1,  1,  1,
  118. 1, -2, -1,
  119. 1, -1, -1},
  120. 1                             // Divisor = 1
  121. };
  122. KERNEL Lap1 = {   // Laplace filter 1
  123. { 0,  1,  0,
  124. 1, -4,  1,
  125. 0,  1,  0},
  126. 1                             // Divisor = 1
  127. };
  128. KERNEL Lap2 = {   // Laplace filter 2
  129. { -1, -1, -1,
  130. -1,  8, -1,
  131. -1, -1, -1},
  132. 1                             // Divisor = 1
  133. };
  134. KERNEL Lap3 = {   // Laplace filter 3
  135. { -1, -1, -1,
  136. -1,  9, -1,
  137. -1, -1, -1},
  138. 1                             // Divisor = 1
  139. };
  140. KERNEL Lap4 = {   // Laplace filter 4
  141. { 1, -2, 1,
  142. -2, 4, -2,
  143. 1, -2, 1},
  144. 1                             // Divisor = 1
  145. };
  146. KERNEL Sobel[4] = {
  147. {                    // Sobel1
  148. {-1, 0, 1,
  149. -2, 0, 2,
  150. -1, 0, 1},
  151. 1                             // Divisor = 1
  152. },
  153. {                    // Sobel2
  154. {-1, -2, -1,
  155. 0,  0,  0,
  156. 1,  2,  1},
  157. 1                             // Divisor = 1
  158. },
  159. {                    // Sobel3
  160. {-2, -1, 0,
  161. -1,  0, 1,
  162. 0,  1, 2},
  163. 1                             // Divisor = 1
  164. },
  165. {                    // Sobel4
  166. {0, -1, -2,
  167. 1,  0, -1,
  168. 2,  1, 0},
  169. 1                             // Divisor = 1
  170. }
  171. };
  172. KERNEL Hough[4] = {
  173. {                    // Hough1
  174. {-1, 0, 1,
  175. -1, 0, 1,
  176. -1, 0, 1},
  177. 1                             // Divisor = 1
  178. },
  179. {                    // Hough2
  180. {-1, -1, 0,
  181. -1,  0, 1,
  182. 0,  1, 1},
  183. 1                             // Divisor = 1
  184. },
  185. {                    // Hough3
  186. {-1, -1, -1,
  187. 0,  0, 0,
  188. 1,  1, 1},
  189. 1                             // Divisor = 1
  190. },
  191. {                    // Hough4
  192. {0, -1, -1,
  193. 1,  0, -1,
  194. 1,  1, 0},
  195. 1                             // Divisor = 1
  196. }
  197. };
  198. CImgProcess::CImgProcess()
  199. {
  200. }
  201. CImgProcess::~CImgProcess()
  202. {
  203. }
  204. // function body
  205. /************************************************************************* 
  206.  * 
  207.  * HighPassDIB() 
  208.  * 
  209.  * Parameters: 
  210.  * 
  211.  * HDIB hDib        - objective DIB handle
  212.  * int nAlgorithm   - specify the filter to use
  213.  * int Strength     - operation strength set to the convolute
  214.  * 
  215.  * Return Value: 
  216.  * 
  217.  * BOOL             - True is success, else False
  218.  * 
  219.  * Description: 
  220.  * 
  221.  * High pass filtering to sharp DIB
  222.  * 
  223.  ************************************************************************/ 
  224. BOOL CImgProcess::HighPassDIB(HDIB hDib, int Strength, int nAlgorithm) 
  225. {
  226. switch (nAlgorithm)
  227. {
  228. case FILTER1:
  229. return ConvoluteDIB(hDib, &HP1, Strength);
  230. case FILTER2:
  231. return ConvoluteDIB(hDib, &HP2, Strength);
  232. case FILTER3:
  233. return ConvoluteDIB(hDib, &HP3, Strength);
  234. }
  235. return FALSE;
  236. }
  237. /************************************************************************* 
  238.  * 
  239.  * LowPassDIB() 
  240.  * 
  241.  * Parameters: 
  242.  * 
  243.  * HDIB hDib        - objective DIB handle
  244.  * int nAlgorithm   - specify the filter to use
  245.  * int Strength     - operation strength set to the convolute
  246.  * 
  247.  * Return Value: 
  248.  * 
  249.  * BOOL             - True is success, else False
  250.  * 
  251.  * Description: 
  252.  * 
  253.  * Low pass filtering to blur DIB
  254.  * 
  255.  ************************************************************************/ 
  256. BOOL CImgProcess::LowPassDIB(HDIB hDib, int Strength, int nAlgorithm) 
  257. {
  258. ASSERT(NULL != hDib);
  259. switch (nAlgorithm)
  260. {
  261. case FILTER1:
  262. return ConvoluteDIB(hDib, &LP1, Strength);
  263. case FILTER2:
  264. return ConvoluteDIB(hDib, &LP2, Strength);
  265. case FILTER3:
  266. return ConvoluteDIB(hDib, &LP3, Strength);
  267. }
  268. return FALSE;
  269. }
  270. /************************************************************************* 
  271.  * 
  272.  * EdgeEnhanceDIB() 
  273.  * 
  274.  * Parameters: 
  275.  * 
  276.  * HDIB hDib        - objective DIB handle
  277.  * int nAlgorithm   - specify the filter to use
  278.  * int Strength     - operation strength set to the convolute
  279.  * 
  280.  * Return Value: 
  281.  * 
  282.  * BOOL             - True is success, else False
  283.  * 
  284.  * Description: 
  285.  * 
  286.  * Edge enhance DIB
  287.  * 
  288.  ************************************************************************/ 
  289. BOOL CImgProcess::EdgeEnhanceDIB(HDIB hDib, int Strength, int nAlgorithm)
  290. {
  291. switch (nAlgorithm)
  292. {
  293. case VERT:
  294. return ConvoluteDIB(hDib, &VertEdge, Strength);
  295. case HORZ:
  296. return ConvoluteDIB(hDib, &HorzEdge, Strength);
  297. case VERTHORZ:
  298. return ConvoluteDIB(hDib, &VertHorzEdge, Strength);
  299. case NORTH:
  300. return ConvoluteDIB(hDib, &EdgeNorth, Strength);
  301. case NORTHEAST:
  302. return ConvoluteDIB(hDib, &EdgeNorthEast, Strength);
  303. case EAST:
  304. return ConvoluteDIB(hDib, &EdgeEast, Strength);
  305. case SOUTH:
  306. return ConvoluteDIB(hDib, &EdgeSouth, Strength);
  307. case SOUTHEAST:
  308. return ConvoluteDIB(hDib, &EdgeSouthEast, Strength);
  309. case SOUTHWEST:
  310. return ConvoluteDIB(hDib, &EdgeSouthWest, Strength);
  311. case WEST:
  312. return ConvoluteDIB(hDib, &EdgeWest, Strength);
  313. case NORTHWEST:
  314. return ConvoluteDIB(hDib, &EdgeNorthWest, Strength);
  315. case LAP1:
  316. return ConvoluteDIB(hDib, &Lap1, Strength);
  317. case LAP2:
  318. return ConvoluteDIB(hDib, &Lap2, Strength);
  319. case LAP3:
  320. return ConvoluteDIB(hDib, &Lap3, Strength);
  321. case LAP4:
  322. return ConvoluteDIB(hDib, &Lap4, Strength);
  323. case SOBEL:
  324. return ConvoluteDIB(hDib, Sobel, Strength, 4);
  325. case HOUGH:
  326. return ConvoluteDIB(hDib, Hough, Strength, 4);
  327. }
  328. return FALSE;
  329. }
  330. /************************************************************************* 
  331.  * 
  332.  * MedianFilterDIB() 
  333.  * 
  334.  * Parameters: 
  335.  * 
  336.  * HDIB hDib        - objective DIB handle
  337.  * 
  338.  * Return Value: 
  339.  * 
  340.  * BOOL             - True is success, else False
  341.  * 
  342.  * Description: 
  343.  * 
  344.  * This is the media filtering function to DIB
  345.  * 
  346.  ************************************************************************/ 
  347. BOOL CImgProcess::MedianFilterDIB(HDIB hDib) 
  348. {
  349. ASSERT(NULL != hDib);
  350. WaitCursorBegin();
  351. HDIB hNewDib = NULL;
  352. // we only convolute 24bpp DIB, so first convert DIB to 24bpp
  353. WORD wBitCount = DIBBitCount(hDib);
  354. if (wBitCount != 24)
  355. hNewDib = ConvertDIBFormat(hDib, 24, NULL);
  356. else
  357. hNewDib = CopyHandle(hDib);
  358. if (! hNewDib)
  359. {
  360. WaitCursorEnd();
  361. return FALSE;
  362. }
  363. // new DIB attributes
  364. WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
  365. WORD wDIBHeight = (WORD)DIBHeight(hNewDib);
  366. WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
  367. DWORD dwImageSize = wBytesPerLine * wDIBHeight;
  368. // Allocate and lock memory for filtered image data
  369. HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
  370. if (!hFilteredBits) 
  371. {
  372. WaitCursorEnd();
  373. return FALSE;
  374. }
  375. LPSTR lpDestImage = (LPSTR)GlobalLock(hFilteredBits);
  376. // get bits address in DIB
  377. LPSTR lpDIB = (LPSTR)GlobalLock(hNewDib);
  378. LPSTR lpDIBits = ::FindDIBBits(lpDIB);
  379. // convolute...
  380. for (int i=1; i<wDIBHeight-1; i++) 
  381. for (int j=1; j<wDIBWidth-1; j++) 
  382. {
  383. int  red=0, green=0, blue=0; 
  384. DoMedianFilterDIB(&red, &green, &blue, i, j, wBytesPerLine, lpDIBits);
  385. LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
  386. *(lpDestImage + lOffset++) = BOUND(blue, 0, 255);
  387. *(lpDestImage + lOffset++) = BOUND(green, 0, 255);
  388. *(lpDestImage + lOffset)   = BOUND(red, 0, 255);
  389. }
  390. // a filtered image is available in lpDestImage
  391. // copy it to DIB bits
  392. memcpy(lpDIBits, lpDestImage, dwImageSize);
  393. // cleanup temp buffers
  394. GlobalUnlock(hFilteredBits);
  395. GlobalFree(hFilteredBits);
  396. GlobalUnlock(hNewDib);
  397. // rebuild hDib
  398. HDIB hTmp = NULL;
  399. if (wBitCount != 24)
  400. hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL);
  401. else
  402. hTmp = CopyHandle(hNewDib);
  403. GlobalFree(hNewDib);
  404. DWORD dwSize = GlobalSize(hTmp);
  405. memcpy((LPSTR)GlobalLock(hDib), (LPSTR)GlobalLock(hTmp), dwSize);
  406. GlobalUnlock(hTmp);
  407. GlobalFree(hTmp);
  408. GlobalUnlock(hDib);
  409. WaitCursorEnd();
  410. return TRUE;
  411. }
  412. /************************************************************************* 
  413.  * 
  414.  * ConvoluteDIB() 
  415.  * 
  416.  * Parameters: 
  417.  * 
  418.  * HDIB hDib        - objective DIB handle
  419.  * KERNEL *lpKernel - pointer of kernel used to convolute with DIB
  420.  * int Strength     - operation strength set to the convolute
  421.  * int nKernelNum   - kernel number used to convolute
  422.  * 
  423.  * Return Value: 
  424.  * 
  425.  * BOOL             - True is success, else False
  426.  * 
  427.  * Description: 
  428.  * 
  429.  * This is the generic convolute function to DIB
  430.  * 
  431.  ************************************************************************/ 
  432. BOOL CImgProcess::ConvoluteDIB(HDIB hDib, KERNEL *lpKernel, int Strength, int nKernelNum) 
  433. {
  434. ASSERT(NULL != hDib);
  435. ASSERT(NULL != lpKernel);
  436. WaitCursorBegin();
  437. HDIB hNewDib = NULL;
  438. // we only convolute 24bpp DIB, so first convert DIB to 24bpp
  439. WORD wBitCount = DIBBitCount(hDib);
  440. if (wBitCount != 24)
  441. hNewDib = ConvertDIBFormat(hDib, 24, NULL);
  442. else
  443. hNewDib = CopyHandle(hDib);
  444. if (! hNewDib)
  445. {
  446. WaitCursorEnd();
  447. return FALSE;
  448. }
  449. // new DIB attributes
  450. WORD wDIBWidth = (WORD)DIBWidth(hNewDib);
  451. WORD wDIBHeight = (WORD)DIBHeight(hNewDib);
  452. WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib);
  453. DWORD dwImageSize = wBytesPerLine * wDIBHeight;
  454. // Allocate and lock memory for filtered image data
  455. HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize);
  456. if (!hFilteredBits) 
  457. {
  458. WaitCursorEnd();
  459. return FALSE;
  460. }
  461. LPSTR lpDestImage = (LPSTR)GlobalLock(hFilteredBits);
  462. // get bits address in DIB
  463. LPSTR lpDIB = (LPSTR)GlobalLock(hNewDib);
  464. LPSTR lpDIBits = ::FindDIBBits(lpDIB);
  465. // convolute...
  466. for (int i=1; i<wDIBHeight-1; i++) 
  467. {
  468. for (int j=1; j<wDIBWidth-1; j++) 
  469. {
  470. int  red=0, green=0, blue=0; 
  471. for (int k=0; k<nKernelNum; ++k)
  472. {
  473. int r=0, g=0, b=0; 
  474. DoConvoluteDIB(&r, &g, &b, i, j, 
  475. wBytesPerLine, lpDIBits, lpKernel+k);
  476. if (r > red)
  477. red = r;
  478. if (g > green)
  479. green = g;
  480. if (b > blue)
  481. blue = b;
  482. //red += r; green += g; blue += b;
  483. }
  484. // original RGB value in center pixel  (j, i)
  485. LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
  486. BYTE OldB = *(lpDIBits + lOffset++);
  487. BYTE OldG = *(lpDIBits + lOffset++);
  488. BYTE OldR = *(lpDIBits + lOffset);
  489. // When we get here, red, green and blue have the new RGB value.
  490. if (Strength != 10) 
  491. {
  492. // Interpolate pixel data
  493. red   = OldR + (((red - OldR) * Strength) / 10);
  494. green = OldG + (((green - OldG) * Strength) / 10);
  495. blue  = OldB + (((blue - OldB) * Strength) / 10);
  496. }
  497. lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
  498. *(lpDestImage + lOffset++) = BOUND(blue, 0, 255);
  499. *(lpDestImage + lOffset++) = BOUND(green, 0, 255);
  500. *(lpDestImage + lOffset)   = BOUND(red, 0, 255);
  501. }
  502. }
  503. // a filtered image is available in lpDestImage
  504. // copy it to DIB bits
  505. memcpy(lpDIBits, lpDestImage, dwImageSize);
  506. // cleanup temp buffers
  507. GlobalUnlock(hFilteredBits);
  508. GlobalFree(hFilteredBits);
  509. GlobalUnlock(hNewDib);
  510. // rebuild hDib
  511. HDIB hTmp = NULL;
  512. if (wBitCount != 24)
  513. hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL);
  514. else
  515. hTmp = CopyHandle(hNewDib);
  516. GlobalFree(hNewDib);
  517. DWORD dwSize = GlobalSize(hTmp);
  518. memcpy((LPSTR)GlobalLock(hDib), (LPSTR)GlobalLock(hTmp), dwSize);
  519. GlobalUnlock(hTmp);
  520. GlobalFree(hTmp);
  521. GlobalUnlock(hDib);
  522. WaitCursorEnd();
  523. return TRUE;
  524. }
  525. // local function: perform convolution to DIB with a kernel
  526. void CImgProcess::DoConvoluteDIB(int *red, int *green, int *blue, int i, int j, 
  527. WORD wBytesPerLine, LPSTR lpDIBits, KERNEL *lpKernel)
  528. {
  529. BYTE b[9], g[9], r[9];
  530. LONG lOffset;
  531. lOffset= PIXEL_OFFSET(i-1,j-1, wBytesPerLine);
  532. b[0] = *(lpDIBits + lOffset++);
  533. g[0] = *(lpDIBits + lOffset++);
  534. r[0] = *(lpDIBits + lOffset);
  535. lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine);
  536. b[1] = *(lpDIBits + lOffset++);
  537. g[1] = *(lpDIBits + lOffset++);
  538. r[1] = *(lpDIBits + lOffset);
  539. lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine);
  540. b[2] = *(lpDIBits + lOffset++);
  541. g[2] = *(lpDIBits + lOffset++);
  542. r[2] = *(lpDIBits + lOffset);
  543. lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine);
  544. b[3] = *(lpDIBits + lOffset++);
  545. g[3] = *(lpDIBits + lOffset++);
  546. r[3] = *(lpDIBits + lOffset);
  547. lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
  548. b[4] = *(lpDIBits + lOffset++);
  549. g[4] = *(lpDIBits + lOffset++);
  550. r[4] = *(lpDIBits + lOffset);
  551. lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine);
  552. b[5] = *(lpDIBits + lOffset++);
  553. g[5] = *(lpDIBits + lOffset++);
  554. r[5] = *(lpDIBits + lOffset);
  555. lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine);
  556. b[6] = *(lpDIBits + lOffset++);
  557. g[6] = *(lpDIBits + lOffset++);
  558. r[6] = *(lpDIBits + lOffset);
  559. lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine);
  560. b[7] = *(lpDIBits + lOffset++);
  561. g[7] = *(lpDIBits + lOffset++);
  562. r[7] = *(lpDIBits + lOffset);
  563. lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine);
  564. b[8] = *(lpDIBits + lOffset++);
  565. g[8] = *(lpDIBits + lOffset++);
  566. r[8] = *(lpDIBits + lOffset);
  567. *red = *green = *blue = 0;
  568. for (int k=0; k<8; ++k)
  569. {
  570. *red   += lpKernel->Element[k]*r[k];
  571. *green += lpKernel->Element[k]*g[k];
  572. *blue  += lpKernel->Element[k]*b[k];
  573. }
  574. if (lpKernel->Divisor != 1) 
  575. {
  576. *red   /= lpKernel->Divisor;
  577. *green /= lpKernel->Divisor;
  578. *blue  /= lpKernel->Divisor;
  579. }
  580. // getoff opposite
  581. *red   = abs(*red);
  582. *green = abs(*green);
  583. *blue  = abs(*blue);
  584. }
  585. // local function: perform median filter to DIB
  586. void CImgProcess::DoMedianFilterDIB(int *red, int *green, int *blue, int i, int j, 
  587. WORD wBytesPerLine, LPSTR lpDIBits)
  588. {
  589. BYTE b[9], g[9], r[9];
  590. LONG lOffset;
  591. lOffset= PIXEL_OFFSET(i-1,j-1, wBytesPerLine);
  592. b[0] = *(lpDIBits + lOffset++);
  593. g[0] = *(lpDIBits + lOffset++);
  594. r[0] = *(lpDIBits + lOffset);
  595. lOffset= PIXEL_OFFSET(i-1,j, wBytesPerLine);
  596. b[1] = *(lpDIBits + lOffset++);
  597. g[1] = *(lpDIBits + lOffset++);
  598. r[1] = *(lpDIBits + lOffset);
  599. lOffset= PIXEL_OFFSET(i-1,j+1, wBytesPerLine);
  600. b[2] = *(lpDIBits + lOffset++);
  601. g[2] = *(lpDIBits + lOffset++);
  602. r[2] = *(lpDIBits + lOffset);
  603. lOffset= PIXEL_OFFSET(i,j-1, wBytesPerLine);
  604. b[3] = *(lpDIBits + lOffset++);
  605. g[3] = *(lpDIBits + lOffset++);
  606. r[3] = *(lpDIBits + lOffset);
  607. lOffset= PIXEL_OFFSET(i,j, wBytesPerLine);
  608. b[4] = *(lpDIBits + lOffset++);
  609. g[4] = *(lpDIBits + lOffset++);
  610. r[4] = *(lpDIBits + lOffset);
  611. lOffset= PIXEL_OFFSET(i,j+1, wBytesPerLine);
  612. b[5] = *(lpDIBits + lOffset++);
  613. g[5] = *(lpDIBits + lOffset++);
  614. r[5] = *(lpDIBits + lOffset);
  615. lOffset= PIXEL_OFFSET(i+1,j-1, wBytesPerLine);
  616. b[6] = *(lpDIBits + lOffset++);
  617. g[6] = *(lpDIBits + lOffset++);
  618. r[6] = *(lpDIBits + lOffset);
  619. lOffset= PIXEL_OFFSET(i+1,j, wBytesPerLine);
  620. b[7] = *(lpDIBits + lOffset++);
  621. g[7] = *(lpDIBits + lOffset++);
  622. r[7] = *(lpDIBits + lOffset);
  623. lOffset= PIXEL_OFFSET(i+1,j+1, wBytesPerLine);
  624. b[8] = *(lpDIBits + lOffset++);
  625. g[8] = *(lpDIBits + lOffset++);
  626. r[8] = *(lpDIBits + lOffset);
  627. //    qsort(r, 9, 1, compare);
  628. //    qsort(g, 9, 1, compare);
  629.  //   qsort(b, 9, 1, compare);
  630. *red   = r[0];
  631. *green = g[0];
  632. *blue  = b[0];
  633. }
  634. // function used to sort in the call of qsort
  635. int CImgProcess::compare(const void *e1, const void *e2)
  636. {
  637. if (*(BYTE *)e1 < *(BYTE *)e2)
  638. return -1;
  639. if (*(BYTE *)e1 > *(BYTE *)e2)
  640. return 1;
  641. return 0;
  642. }
  643. /************************************************************************* 
  644.  * 
  645.  * ReverseDIB() 
  646.  * 
  647.  * Parameters: 
  648.  * 
  649.  * HDIB hDib        - objective DIB handle
  650.  * 
  651.  * Return Value: 
  652.  * 
  653.  * BOOL             - True is success, else False
  654.  * 
  655.  * Description: 
  656.  * 
  657.  * This function reverse DIB
  658.  * 
  659.  ************************************************************************/ 
  660. BOOL CImgProcess::ReverseDIB(HDIB hDib) 
  661. {
  662. WaitCursorBegin();
  663. HDIB hNewDib = NULL;
  664. // only support 256 grayscale image
  665. WORD wBitCount = DIBBitCount(hDib);
  666. if (wBitCount != 8)
  667. {
  668. WaitCursorEnd();
  669. return FALSE;
  670. }
  671. // the maxium pixel value
  672. int  nMaxValue = 256;
  673. // source pixel data
  674.     LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
  675. if (! lpSrcDIB)
  676. {
  677. WaitCursorBegin();
  678. return FALSE;
  679. }
  680. // new DIB attributes
  681. LPSTR lpPtr;
  682. LONG lHeight = DIBHeight(lpSrcDIB);
  683. LONG lWidth = DIBWidth(lpSrcDIB);
  684. DWORD dwBufferSize = GlobalSize(hDib);
  685. int nLineBytes = BytesPerLine(lpSrcDIB);
  686. // convolute...
  687. for (long i=0; i<lHeight; i++) 
  688. for (long j=0; j<lWidth; j++) 
  689. {
  690. lpPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-i*nLineBytes)+j;
  691. *lpPtr = nMaxValue - *lpPtr;
  692. }
  693. // cleanup
  694. GlobalUnlock(hDib);
  695. WaitCursorEnd();
  696. return TRUE;
  697. }
  698. /************************************************************************* 
  699.  * 
  700.  * ErosionDIB() 
  701.  * 
  702.  * Parameters: 
  703.  * 
  704.  * HDIB hDib        - objective DIB handle
  705.  * BOOL bHori     - erosion direction
  706.  * 
  707.  * Return Value: 
  708.  * 
  709.  * BOOL             - True is success, else False
  710.  * 
  711.  * Description: 
  712.  * 
  713.  * This function do erosion with the specified direction
  714.  * 
  715.  ************************************************************************/ 
  716. BOOL CImgProcess::ErosionDIB(HDIB hDib, BOOL bHori)
  717. {
  718. // start wait cursor
  719. WaitCursorBegin();
  720.     // Old DIB buffer
  721. if (hDib == NULL)
  722. {
  723. WaitCursorEnd();
  724.         return FALSE;
  725. }
  726. // only support 256 color image
  727. WORD wBitCount = DIBBitCount(hDib);
  728. if (wBitCount != 8)
  729. {
  730. WaitCursorEnd();
  731.         return FALSE;
  732. }
  733. // new DIB
  734. HDIB hNewDIB = CopyHandle(hDib);
  735. if (! hNewDIB)
  736. {
  737. WaitCursorEnd();
  738.         return FALSE;
  739. }
  740. // source dib buffer
  741.     LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
  742. if (! lpSrcDIB)
  743. {
  744. WaitCursorBegin();
  745. return FALSE;
  746. }
  747.     // New DIB buffer
  748.     LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
  749. if (! lpbmi)
  750. {
  751. WaitCursorBegin();
  752. return FALSE;
  753. }
  754. // start erosion...
  755. LPSTR lpPtr;
  756. LPSTR lpTempPtr;
  757. LONG  x,y;
  758. BYTE  num, num0;
  759. int   i;
  760. LONG lHeight = DIBHeight(lpSrcDIB);
  761. LONG lWidth = DIBWidth(lpSrcDIB);
  762. DWORD dwBufferSize = GlobalSize(lpSrcDIB);
  763. int nLineBytes = BytesPerLine(lpSrcDIB);
  764. if(bHori)
  765. {
  766. for (y=0; y<lHeight; y++)
  767. {
  768. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  769. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  770. for (x=1; x<lWidth-1; x++)
  771. {
  772. num0 = num = 0 ;
  773. for(i=0;i<3;i++)
  774. {
  775. num=(unsigned char)*(lpPtr+i-1);
  776. if(num > num0)
  777. num0 = num;
  778. }
  779. *lpTempPtr=(unsigned char)num0;
  780. /*
  781. num=(unsigned char)*lpPtr;
  782. if (num==0)
  783. {
  784. *lpTempPtr=(unsigned char)0;
  785. for(i=0;i<3;i++)
  786. {
  787. num=(unsigned char)*(lpPtr+i-1);
  788. if(num==255)
  789. {
  790. *lpTempPtr=(unsigned char)255;
  791. break;
  792. }
  793. }
  794. }
  795. else 
  796. *lpTempPtr=(unsigned char)255;
  797. */
  798. lpPtr++;
  799. lpTempPtr++;
  800. }
  801. }
  802. }
  803. else // Vertical
  804. {
  805. for (y=1; y<lHeight-1; y++)
  806. {
  807. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  808. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  809. for (x=0; x<lWidth; x++)
  810. {
  811. num0 = num = 0 ;
  812. for(i=0;i<3;i++)
  813. {
  814. num=(unsigned char)*(lpPtr+i-1);
  815. if(num > num0)
  816. num0 = num;
  817. }
  818. *lpTempPtr=(unsigned char)num0;
  819. /*
  820. num=(unsigned char)*lpPtr;
  821. if (num==0)
  822. {
  823. *lpTempPtr=(unsigned char)0;
  824. for(i=0;i<3;i++)
  825. {
  826. num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
  827. if(num==255)
  828. {
  829. *lpTempPtr=(unsigned char)255;
  830. break;
  831. }
  832. }
  833. }
  834. else 
  835. *lpTempPtr=(unsigned char)255;
  836. */
  837. lpPtr++;
  838. lpTempPtr++;
  839. }
  840. }
  841. }
  842. // cleanup
  843. GlobalUnlock(hDib);
  844. GlobalUnlock(hNewDIB);
  845. GlobalFree(hNewDIB);
  846. WaitCursorEnd();
  847. return TRUE;
  848. }
  849. /************************************************************************* 
  850.  * 
  851.  * DilationDIB() 
  852.  * 
  853.  * Parameters: 
  854.  * 
  855.  * HDIB hDib        - objective DIB handle
  856.  * BOOL bHori     - dilation direction
  857.  * 
  858.  * Return Value: 
  859.  * 
  860.  * BOOL             - True is success, else False
  861.  * 
  862.  * Description: 
  863.  * 
  864.  * This function do dilation with the specified direction
  865.  * 
  866.  ************************************************************************/ 
  867. BOOL CImgProcess::DilationDIB(HDIB hDib, BOOL bHori)
  868. {
  869. // start wait cursor
  870. WaitCursorBegin();
  871.     // Old DIB buffer
  872. if (hDib == NULL)
  873. {
  874. WaitCursorEnd();
  875.         return FALSE;
  876. }
  877. // only support 256 color image
  878. WORD wBitCount = DIBBitCount(hDib);
  879. if (wBitCount != 8)
  880. {
  881. WaitCursorEnd();
  882.         return FALSE;
  883. }
  884. // new DIB
  885. HDIB hNewDIB = CopyHandle(hDib);
  886. if (! hNewDIB)
  887. {
  888. WaitCursorEnd();
  889.         return FALSE;
  890. }
  891. // source dib buffer
  892.     LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
  893. if (! lpSrcDIB)
  894. {
  895. WaitCursorBegin();
  896. return FALSE;
  897. }
  898.     // New DIB buffer
  899.     LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
  900. if (! lpbmi)
  901. {
  902. WaitCursorBegin();
  903. return FALSE;
  904. }
  905. // start erosion...
  906. LPSTR lpPtr;
  907. LPSTR lpTempPtr;
  908. LONG  x,y;
  909. BYTE  num, num0;
  910. int   i;
  911. LONG lHeight = DIBHeight(lpSrcDIB);
  912. LONG lWidth = DIBWidth(lpSrcDIB);
  913. DWORD dwBufferSize = GlobalSize(lpSrcDIB);
  914. int nLineBytes = BytesPerLine(lpSrcDIB);
  915. if(bHori)
  916. {
  917. for(y=0;y<lHeight;y++)
  918. {
  919. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  920. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  921. for(x=1;x<lWidth-1;x++)
  922. {
  923. num0 = num = 255;
  924. for(i=0;i<3;i++)
  925. {
  926. num=(unsigned char)*(lpPtr+i-1);
  927. if(num < num0)
  928. num0 = num;
  929. }
  930. *lpTempPtr=(unsigned char)num0;
  931. /*
  932. num=(unsigned char)*lpPtr;
  933. if (num==255)
  934. {
  935. *lpTempPtr=(unsigned char)255;
  936. for(i=0;i<3;i++)
  937. {
  938. num=(unsigned char)*(lpPtr+i-1);
  939. if(num==0)
  940. {
  941. *lpTempPtr=(unsigned char)0;
  942. break;
  943. }
  944. }
  945. }
  946. else 
  947. *lpTempPtr=(unsigned char)0;
  948. */
  949. lpPtr++;
  950. lpTempPtr++;
  951. }
  952. }
  953. }
  954. else
  955. {
  956. for(y=1;y<lHeight-1;y++)
  957. {
  958. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  959. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  960. for(x=0;x<lWidth;x++)
  961. {
  962. num0 = num = 255;
  963. for(i=0;i<3;i++)
  964. {
  965. num=(unsigned char)*(lpPtr+i-1);
  966. if(num < num0)
  967. num0 = num;
  968. }
  969. *lpTempPtr=(unsigned char)num0;
  970. /*
  971. num=(unsigned char)*lpPtr;
  972. if (num==255)
  973. {
  974. *lpTempPtr=(unsigned char)255;
  975. for(i=0;i<3;i++)
  976. {
  977. num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
  978. if(num==0)
  979. {
  980. *lpTempPtr=(unsigned char)0;
  981. break;
  982. }
  983. }
  984. }
  985. else 
  986. *lpTempPtr=(unsigned char)0;
  987. */
  988. lpPtr++;
  989. lpTempPtr++;
  990. }
  991. }
  992. }
  993. // cleanup
  994. GlobalUnlock(hDib);
  995. GlobalUnlock(hNewDIB);
  996. GlobalFree(hNewDIB);
  997. WaitCursorEnd();
  998. return TRUE;
  999. }
  1000. /************************************************************************* 
  1001.  * 
  1002.  * MorphOpenDIB() 
  1003.  * 
  1004.  * Parameters: 
  1005.  * 
  1006.  * HDIB hDib        - objective DIB handle
  1007.  * BOOL bHori     - open direction
  1008.  * 
  1009.  * Return Value: 
  1010.  * 
  1011.  * BOOL             - True is success, else False
  1012.  * 
  1013.  * Description: 
  1014.  * 
  1015.  * This function do open with the specified direction
  1016.  * 
  1017.  ************************************************************************/ 
  1018. BOOL CImgProcess::MorphOpenDIB(HDIB hDib, BOOL bHori)
  1019. {
  1020. // Step 1: erosion
  1021. if (! ErosionDIB(hDib, bHori))
  1022. return FALSE;
  1023. // Step 2: dilation
  1024. if (! DilationDIB(hDib, bHori))
  1025. return FALSE;
  1026. return TRUE;
  1027. }
  1028. /************************************************************************* 
  1029.  * 
  1030.  * MorphCloseDIB() 
  1031.  * 
  1032.  * Parameters: 
  1033.  * 
  1034.  * HDIB hDib        - objective DIB handle
  1035.  * BOOL bHori     - close direction
  1036.  * 
  1037.  * Return Value: 
  1038.  * 
  1039.  * BOOL             - True is success, else False
  1040.  * 
  1041.  * Description: 
  1042.  * 
  1043.  * This function do close with the specified direction
  1044.  * 
  1045.  ************************************************************************/ 
  1046. BOOL CImgProcess::MorphCloseDIB(HDIB hDib, BOOL bHori)
  1047. {
  1048. // Step 1: dilation
  1049. if (! DilationDIB(hDib, bHori))
  1050. return FALSE;
  1051. // Step 2: erosion
  1052. if (! ErosionDIB(hDib, bHori))
  1053. return FALSE;
  1054. return TRUE;
  1055. }
  1056. /************************************************************************* 
  1057.  * 
  1058.  * ContourDIB() 
  1059.  * 
  1060.  * Parameters: 
  1061.  * 
  1062.  * HDIB hDib        - objective DIB handle
  1063.  * BOOL bHori     - open direction
  1064.  * 
  1065.  * Return Value: 
  1066.  * 
  1067.  * BOOL             - True is success, else False
  1068.  * 
  1069.  * Description: 
  1070.  * 
  1071.  * This function contour DIB with the specified direction
  1072.  * 
  1073.  ************************************************************************/ 
  1074. BOOL CImgProcess::ContourDIB(HDIB hDib, BOOL bHori)
  1075. {
  1076. // start wait cursor
  1077. WaitCursorBegin();
  1078.     // Old DIB buffer
  1079. if (hDib == NULL)
  1080. {
  1081. WaitCursorEnd();
  1082.         return FALSE;
  1083. }
  1084. // only support 256 color image
  1085. WORD wBitCount = DIBBitCount(hDib);
  1086. if (wBitCount != 8)
  1087. {
  1088. WaitCursorEnd();
  1089.         return FALSE;
  1090. }
  1091. // new DIB
  1092. HDIB hNewDIB = CopyHandle(hDib);
  1093. if (! hNewDIB)
  1094. {
  1095. WaitCursorEnd();
  1096.         return FALSE;
  1097. }
  1098. // source dib buffer
  1099.     LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
  1100. if (! lpSrcDIB)
  1101. {
  1102. WaitCursorBegin();
  1103. return FALSE;
  1104. }
  1105.     // New DIB buffer
  1106.     LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
  1107. if (! lpbmi)
  1108. {
  1109. WaitCursorBegin();
  1110. return FALSE;
  1111. }
  1112. // start erosion...
  1113. LPSTR lpPtr;
  1114. LPSTR lpTempPtr;
  1115. LONG  x,y;
  1116. BYTE  num, num0;
  1117. int   i;
  1118. LONG lHeight = DIBHeight(lpSrcDIB);
  1119. LONG lWidth = DIBWidth(lpSrcDIB);
  1120. DWORD dwBufferSize = GlobalSize(lpSrcDIB);
  1121. int nLineBytes = BytesPerLine(lpSrcDIB);
  1122. // Step 1: erosion
  1123. if(bHori)
  1124. {
  1125. for (y=0; y<lHeight; y++)
  1126. {
  1127. lpPtr=(LPSTR)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  1128. lpTempPtr=(LPSTR)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  1129. for (x=1; x<lWidth-1; x++)
  1130. {
  1131. num0 = num = 0 ;
  1132. for(i=0;i<3;i++)
  1133. {
  1134. num=(unsigned char)*(lpPtr+i-1);
  1135. if(num > num0)
  1136. num0 = num;
  1137. }
  1138. *lpTempPtr=(unsigned char)num0;
  1139. /*
  1140. num=(unsigned char)*lpPtr;
  1141. if (num==0)
  1142. {
  1143. *lpTempPtr=(unsigned char)0;
  1144. for(i=0;i<3;i++)
  1145. {
  1146. num=(unsigned char)*(lpPtr+i-1);
  1147. if(num==255)
  1148. {
  1149. *lpTempPtr=(unsigned char)255;
  1150. break;
  1151. }
  1152. }
  1153. }
  1154. else 
  1155. *lpTempPtr=(unsigned char)255;
  1156. */
  1157. lpPtr++;
  1158. lpTempPtr++;
  1159. }
  1160. }
  1161. }
  1162. else // Vertical
  1163. {
  1164. for (y=1; y<lHeight-1; y++)
  1165. {
  1166. lpPtr=(LPSTR)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  1167. lpTempPtr=(LPSTR)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  1168. for (x=0; x<lWidth; x++)
  1169. {
  1170. num0 = num = 0 ;
  1171. for(i=0;i<3;i++)
  1172. {
  1173. num=(unsigned char)*(lpPtr+i-1);
  1174. if(num > num0)
  1175. num0 = num;
  1176. }
  1177. *lpTempPtr=(unsigned char)num0;
  1178. /*
  1179. num=(unsigned char)*lpPtr;
  1180. if (num==0)
  1181. {
  1182. *lpTempPtr=(unsigned char)0;
  1183. for(i=0;i<3;i++)
  1184. {
  1185. num=(unsigned char)*(lpPtr+(i-1)*nLineBytes);
  1186. if(num==255)
  1187. {
  1188. *lpTempPtr=(unsigned char)255;
  1189. break;
  1190. }
  1191. }
  1192. }
  1193. else 
  1194. *lpTempPtr=(unsigned char)255;
  1195. */
  1196. lpPtr++;
  1197. lpTempPtr++;
  1198. }
  1199. }
  1200. }
  1201. // Step 2: original image minues dilation image
  1202. if(bHori)
  1203. {
  1204. for(y=0;y<lHeight;y++)
  1205. {
  1206. lpPtr=(LPSTR)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  1207. lpTempPtr=(LPSTR)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes)+1;
  1208. for(x=1;x<lWidth-1;x++)
  1209. {
  1210. if (*lpTempPtr == *lpPtr)
  1211. *lpTempPtr = (BYTE)255;
  1212. else
  1213. *lpTempPtr = *lpTempPtr - *lpPtr;
  1214. lpPtr++;
  1215. lpTempPtr++;
  1216. }
  1217. }
  1218. }
  1219. else
  1220. {
  1221. for(y=1;y<lHeight-1;y++)
  1222. {
  1223. lpPtr=(LPSTR)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  1224. lpTempPtr=(LPSTR)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  1225. for(x=0;x<lWidth;x++)
  1226. {
  1227. if (*lpTempPtr == *lpPtr)
  1228. *lpTempPtr = (BYTE)255;
  1229. else
  1230. *lpTempPtr = *lpTempPtr - *lpPtr;
  1231. lpPtr++;
  1232. lpTempPtr++;
  1233. }
  1234. }
  1235. }
  1236. // cleanup
  1237. GlobalUnlock(hDib);
  1238. GlobalUnlock(hNewDIB);
  1239. GlobalFree(hNewDIB);
  1240. return TRUE;
  1241. }
  1242. /************************************************************************* 
  1243.  * 
  1244.  * ThinningDIB() 
  1245.  * 
  1246.  * Parameters: 
  1247.  * 
  1248.  * HDIB hDib        - objective DIB handle
  1249.  * 
  1250.  * Return Value: 
  1251.  * 
  1252.  * BOOL             - True is success, else False
  1253.  * 
  1254.  * Description: 
  1255.  * 
  1256.  * This function thins a DIB
  1257.  * 
  1258.  ************************************************************************/ 
  1259. BOOL CImgProcess::ThinningDIB(HDIB hDib)
  1260. {
  1261. static int erasetable[256]=
  1262. {
  1263. 0,0,1,1,0,0,1,1,
  1264. 1,1,0,1,1,1,0,1,
  1265. 1,1,0,0,1,1,1,1,
  1266. 0,0,0,0,0,0,0,1,
  1267. 0,0,1,1,0,0,1,1,
  1268. 1,1,0,1,1,1,0,1,
  1269. 1,1,0,0,1,1,1,1,
  1270. 0,0,0,0,0,0,0,1,
  1271. 1,1,0,0,1,1,0,0,
  1272. 0,0,0,0,0,0,0,0,
  1273. 0,0,0,0,0,0,0,0,
  1274. 0,0,0,0,0,0,0,0,
  1275. 1,1,0,0,1,1,0,0,
  1276. 1,1,0,1,1,1,0,1,
  1277. 0,0,0,0,0,0,0,0,
  1278. 0,0,0,0,0,0,0,0,
  1279. 0,0,1,1,0,0,1,1,
  1280. 1,1,0,1,1,1,0,1,
  1281. 1,1,0,0,1,1,1,1,
  1282. 0,0,0,0,0,0,0,1,
  1283. 0,0,1,1,0,0,1,1,
  1284. 1,1,0,1,1,1,0,1,
  1285. 1,1,0,0,1,1,1,1,
  1286. 0,0,0,0,0,0,0,0,
  1287. 1,1,0,0,1,1,0,0,
  1288. 0,0,0,0,0,0,0,0,
  1289. 1,1,0,0,1,1,1,1,
  1290. 0,0,0,0,0,0,0,0,
  1291. 1,1,0,0,1,1,0,0,
  1292. 1,1,0,1,1,1,0,0,
  1293. 1,1,0,0,1,1,1,0,
  1294. 1,1,0,0,1,0,0,0
  1295. };
  1296. // start wait cursor
  1297. WaitCursorBegin();
  1298.     // Old DIB buffer
  1299. if (hDib == NULL)
  1300. {
  1301. WaitCursorEnd();
  1302.         return FALSE;
  1303. }
  1304. // only support 256 color image
  1305. WORD wBitCount = DIBBitCount(hDib);
  1306. if (wBitCount != 8)
  1307. {
  1308. WaitCursorEnd();
  1309.         return FALSE;
  1310. }
  1311. // new DIB
  1312. HDIB hNewDIB = CopyHandle(hDib);
  1313. if (! hNewDIB)
  1314. {
  1315. WaitCursorEnd();
  1316.         return FALSE;
  1317. }
  1318. // source dib buffer
  1319.     LPBITMAPINFO lpSrcDIB = (LPBITMAPINFO)GlobalLock(hDib);
  1320. if (! lpSrcDIB)
  1321. {
  1322. WaitCursorBegin();
  1323. return FALSE;
  1324. }
  1325.     // New DIB buffer
  1326.     LPBITMAPINFO lpbmi = (LPBITMAPINFO)GlobalLock(hNewDIB);
  1327. if (! lpbmi)
  1328. {
  1329. WaitCursorBegin();
  1330. return FALSE;
  1331. }
  1332. // start erosion...
  1333. LPSTR lpPtr;
  1334. LPSTR lpTempPtr;
  1335. LONG  x,y;
  1336. BYTE  num;
  1337. LONG lHeight = DIBHeight(lpSrcDIB);
  1338. LONG lWidth = DIBWidth(lpSrcDIB);
  1339. DWORD dwBufferSize = GlobalSize(lpSrcDIB);
  1340. int nLineBytes = BytesPerLine(lpSrcDIB);
  1341. int nw,n,ne,w,e,sw,s,se;
  1342. BOOL Finished=FALSE;
  1343.     while(!Finished)
  1344. {
  1345.      Finished=TRUE;
  1346. for (y=1;y<lHeight-1;y++)
  1347. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  1348. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  1349. x=1; 
  1350. while(x<lWidth-1)
  1351. {
  1352. if(*(lpPtr+x)==0)
  1353. {
  1354. w=(unsigned char)*(lpPtr+x-1);
  1355. e=(unsigned char)*(lpPtr+x+1);
  1356. if( (w==255)|| (e==255))
  1357. {
  1358. nw=(unsigned char)*(lpPtr+x+nLineBytes-1);
  1359. n=(unsigned char)*(lpPtr+x+nLineBytes);
  1360. ne=(unsigned char)*(lpPtr+x+nLineBytes+1);
  1361. sw=(unsigned char)*(lpPtr+x-nLineBytes-1);
  1362. s=(unsigned char)*(lpPtr+x-nLineBytes);
  1363. se=(unsigned char)*(lpPtr+x-nLineBytes+1);
  1364. num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
  1365. if(erasetable[num]==1)
  1366. {
  1367. *(lpPtr+x)=(BYTE)255;
  1368. *(lpTempPtr+x)=(BYTE)255;
  1369. Finished=FALSE;
  1370. x++;
  1371. }
  1372. }
  1373. }
  1374. x++;
  1375. }
  1376. }
  1377. for (x=1;x<lWidth-1;x++)
  1378. y=1;
  1379. while(y<lHeight-1)
  1380. {
  1381. lpPtr=(char *)lpbmi+(dwBufferSize-nLineBytes-y*nLineBytes);
  1382. lpTempPtr=(char *)lpSrcDIB+(dwBufferSize-nLineBytes-y*nLineBytes);
  1383. if(*(lpPtr+x)==0)
  1384. {
  1385. n=(unsigned char)*(lpPtr+x+nLineBytes);
  1386. s=(unsigned char)*(lpPtr+x-nLineBytes);
  1387. if( (n==255)|| (s==255))
  1388. {
  1389. nw=(unsigned char)*(lpPtr+x+nLineBytes-1);
  1390. ne=(unsigned char)*(lpPtr+x+nLineBytes+1);
  1391. w=(unsigned char)*(lpPtr+x-1);
  1392. e=(unsigned char)*(lpPtr+x+1);
  1393. sw=(unsigned char)*(lpPtr+x-nLineBytes-1);
  1394. se=(unsigned char)*(lpPtr+x-nLineBytes+1);
  1395. num=nw/255+n/255*2+ne/255*4+w/255*8+e/255*16+sw/255*32+s/255*64+se/255*128;
  1396. if(erasetable[num]==1)
  1397. {
  1398. *(lpPtr+x)=(BYTE)255;
  1399. *(lpTempPtr+x)=(BYTE)255;
  1400. Finished=FALSE;
  1401. y++;
  1402. }
  1403. }
  1404. }
  1405. y++;
  1406. }
  1407. }
  1408. // cleanup
  1409. GlobalUnlock(hDib);
  1410. GlobalUnlock(hNewDIB);
  1411. GlobalFree(hNewDIB);
  1412. return TRUE;
  1413. }
  1414. //////////////////////////////////////////////////////////
  1415. // internal definitions
  1416. //#define PAI (double)3.14159265359
  1417. //////////////////////////////////////////////////////////////////////////////////
  1418. // internal functions
  1419. void CImgProcess::GetPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
  1420. {
  1421. int x,y,p;
  1422. int nByteWidth = WIDTHBYTES(nWidth*24); //nWidth*3;
  1423. //if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  1424. for(y=0;y<nHeight;y++)
  1425. {
  1426. for(x=0;x<nWidth;x++)
  1427. {
  1428. p=x*3+y*nByteWidth;
  1429. lpPoints[x+y*nWidth]=(BYTE)(0.299*(float)lpBits[p+2]+0.587*(float)lpBits[p+1]+0.114*(float)lpBits[p]+0.1);
  1430. }
  1431. }
  1432. }
  1433. void CImgProcess::PutPoints(int nWidth,int nHeight,BYTE *lpBits,BYTE *lpPoints)
  1434. {
  1435. int x,y,p,p1;
  1436. int nByteWidth = WIDTHBYTES(nWidth*24); //nWidth*3;
  1437. //if (nByteWidth%4) nByteWidth+=4-(nByteWidth%4);
  1438. for(y=0;y<nHeight;y++)
  1439. {
  1440. for(x=0;x<nWidth;x++)
  1441. {
  1442. p=x*3+y*nByteWidth;
  1443. p1=x+y*nWidth;
  1444. lpBits[p]=lpPoints[p1];
  1445. lpBits[p+1]=lpPoints[p1];
  1446. lpBits[p+2]=lpPoints[p1];
  1447. }
  1448. }
  1449. }
  1450. //////////////////////////////////////////////////////////////////////////////
  1451. /****************************************************
  1452. FFTDIB()
  1453. 参数:
  1454. hDIB为输入的DIB句柄
  1455. 返回值:
  1456. 成功为TRUE;失败为FALSE
  1457. 说明:
  1458. 本函数实现DIB位图的快速傅立叶变换
  1459. ****************************************************/
  1460. BOOL CImgProcess::FFTDIB(HDIB hDIB)
  1461. {
  1462. if (hDIB == NULL)
  1463. return FALSE;
  1464. // start wait cursor
  1465. WaitCursorBegin();
  1466. HDIB hDib = NULL;
  1467. HDIB hNewDib = NULL;
  1468. // we only convolute 24bpp DIB, so first convert DIB to 24bpp
  1469. WORD wBitCount = DIBBitCount(hDIB);
  1470. if (wBitCount != 24)
  1471. {
  1472. hNewDib = ConvertDIBFormat(hDIB, 24, NULL);
  1473. hDib = CopyHandle(hNewDib);
  1474. }
  1475. else
  1476. {
  1477. hNewDib = CopyHandle(hDIB);
  1478. hDib = CopyHandle(hDIB);
  1479. }
  1480. if (hNewDib == NULL && hDib == NULL)
  1481. {
  1482. WaitCursorEnd();
  1483. return FALSE;
  1484. }
  1485. // process!
  1486. LPSTR lpSrcDIB = (LPSTR)GlobalLock(hDib);
  1487. LPSTR lpDIB = (LPSTR)GlobalLock(hNewDib);
  1488. LPSTR lpInput = FindDIBBits(lpSrcDIB);
  1489. LPSTR lpOutput = FindDIBBits(lpDIB);
  1490. int nWidth = DIBWidth(lpSrcDIB);
  1491. int nHeight = DIBHeight(lpSrcDIB);
  1492. int w=1,h=1,wp=0,hp=0;
  1493. while(w*2<=nWidth)
  1494. {
  1495. w*=2;
  1496. wp++;
  1497. }
  1498. while(h*2<=nHeight)
  1499. {
  1500. h*=2;
  1501. hp++;
  1502. }
  1503. int x,y;
  1504. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1505. GetPoints(nWidth,nHeight,(BYTE*)lpInput,lpPoints);
  1506. COMPLEX *TD=new COMPLEX[w*h];
  1507. COMPLEX *FD=new COMPLEX[w*h];
  1508. for(y=0;y<h;y++)
  1509. {
  1510. for(x=0;x<w;x++)
  1511. {
  1512. TD[x+w*y].re = lpPoints[x + y * nWidth];
  1513. TD[x+w*y].im = 0;
  1514. }
  1515. }
  1516. for(y=0;y<h;y++)
  1517. {
  1518. if(!CMathEx::FFT(&TD[w*y],&FD[w*y],wp))
  1519. {
  1520. GlobalFree(hDib);
  1521. GlobalFree(hNewDib);
  1522. delete TD;
  1523. delete FD;
  1524. delete lpPoints;
  1525. return FALSE;
  1526. }
  1527. }
  1528. for(y=0;y<h;y++)
  1529. {
  1530. for(x=0;x<w;x++)
  1531. {
  1532. TD[y+h*x]=FD[x+w*y];
  1533. // TD[x+w*y]=FD[x*h+y];
  1534. }
  1535. }
  1536. for(x=0;x<w;x++)
  1537. {
  1538. if(!CMathEx::FFT(&TD[x*h],&FD[x*h],hp))
  1539. {
  1540. GlobalFree(hDib);
  1541. GlobalFree(hNewDib);
  1542. delete TD;
  1543. delete FD;
  1544. delete lpPoints;
  1545. return FALSE;
  1546. }
  1547. }
  1548. memset(lpPoints,0,nWidth*nHeight);
  1549. double m;
  1550. for(y=0;y<h;y++)
  1551. {
  1552. for(x=0;x<w;x++)
  1553. {
  1554. m = sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100;
  1555. if (m>255) m=255;
  1556. // Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m);
  1557. lpPoints[(x < w/2 ? x+w/2 : x-w/2) + (nHeight-1-(y<h/2 ? y+h/2 : y-h/2)) * nWidth] = (BYTE)(m);
  1558. }
  1559. }
  1560. delete TD;
  1561. delete FD;
  1562. PutPoints(nWidth,nHeight,(BYTE*)lpOutput,lpPoints);
  1563. delete lpPoints;
  1564. // recover
  1565. DWORD dwSize = GlobalSize(hDib);
  1566. memcpy(lpSrcDIB, lpDIB, dwSize);
  1567. GlobalUnlock(hDib);
  1568. GlobalUnlock(hNewDib);
  1569. if (wBitCount != 24)
  1570. {
  1571. hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);
  1572. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1573. lpDIB = (LPSTR)GlobalLock(hNewDib);
  1574. dwSize = GlobalSize(hNewDib);
  1575. memcpy(lpSrcDIB, lpDIB, dwSize);
  1576. GlobalUnlock(hDIB);
  1577. GlobalUnlock(hNewDib);
  1578. }
  1579. else
  1580. {
  1581. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1582. lpDIB = (LPSTR)GlobalLock(hDib);
  1583. dwSize = GlobalSize(hDib);
  1584. memcpy(lpSrcDIB, lpDIB, dwSize);
  1585. GlobalUnlock(hDIB);
  1586. GlobalUnlock(hDib);
  1587. }
  1588. // cleanup
  1589. GlobalFree(hDib);
  1590. GlobalFree(hNewDib);
  1591. // return
  1592. WaitCursorEnd();
  1593. return TRUE;
  1594. }
  1595. /****************************************************
  1596. DCTDIB()
  1597. 参数:
  1598. hDIB为输入的DIB句柄
  1599. 返回值:
  1600. 成功为TRUE;失败为FALSE
  1601. 说明:
  1602. 本函数实现DIB位图的快速余弦变换
  1603. ****************************************************/
  1604. BOOL CImgProcess::DCTDIB(HDIB hDIB)
  1605. {
  1606. if (hDIB == NULL)
  1607. return FALSE;
  1608. // start wait cursor
  1609. WaitCursorBegin();
  1610. HDIB hDib = NULL;
  1611. HDIB hNewDib = NULL;
  1612. // we only convolute 24bpp DIB, so first convert DIB to 24bpp
  1613. WORD wBitCount = DIBBitCount(hDIB);
  1614. if (wBitCount != 24)
  1615. {
  1616. hNewDib = ConvertDIBFormat(hDIB, 24, NULL);
  1617. hDib = CopyHandle(hNewDib);
  1618. }
  1619. else
  1620. {
  1621. hNewDib = CopyHandle(hDIB);
  1622. hDib = CopyHandle(hDIB);
  1623. }
  1624. if (hNewDib == NULL && hDib == NULL)
  1625. {
  1626. WaitCursorEnd();
  1627. return FALSE;
  1628. }
  1629. // process!
  1630. LPSTR lpSrcDIB = (LPSTR)GlobalLock(hDib);
  1631. LPSTR lpDIB = (LPSTR)GlobalLock(hNewDib);
  1632. LPSTR lpInput = FindDIBBits(lpSrcDIB);
  1633. LPSTR lpOutput = FindDIBBits(lpDIB);
  1634. int nWidth = DIBWidth(lpSrcDIB);
  1635. int nHeight = DIBHeight(lpSrcDIB);
  1636. int w=1,h=1,wp=0,hp=0;
  1637. while(w*2<=nWidth)
  1638. {
  1639. w*=2;
  1640. wp++;
  1641. }
  1642. while(h*2<=nHeight)
  1643. {
  1644. h*=2;
  1645. hp++;
  1646. }
  1647. int x,y;
  1648. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1649. GetPoints(nWidth,nHeight,(BYTE*)lpInput,lpPoints);
  1650. double *f=new double[w*h];
  1651. double *W=new double[w*h];
  1652. for(y=0;y<h;y++)
  1653. {
  1654. for(x=0;x<w;x++)
  1655. {
  1656. f[x+y*w] = lpPoints[x + y * nWidth];
  1657. }
  1658. }
  1659. for(y=0;y<h;y++)
  1660. {
  1661. CMathEx::DCT(&f[w*y],&W[w*y],wp);
  1662. }
  1663. for(y=0;y<h;y++)
  1664. {
  1665. for(x=0;x<w;x++)
  1666. {
  1667. f[x*h+y]=W[x+w*y];
  1668. }
  1669. }
  1670. for(x=0;x<w;x++)
  1671. {
  1672. CMathEx::DCT(&f[x*h],&W[x*h],hp);
  1673. }
  1674. double a;
  1675. memset(lpPoints,0,nWidth*nHeight);
  1676. for(y=0;y<h;y++)
  1677. {
  1678. for(x=0;x<w;x++)
  1679. {
  1680. a=fabs(W[x*h+y]);
  1681. if (a>255) a=255;
  1682. lpPoints[x + (nHeight-y-1) * nWidth] = (BYTE)(a);
  1683. }
  1684. }
  1685. delete f;
  1686. delete W;
  1687. PutPoints(nWidth,nHeight,(BYTE*)lpOutput,lpPoints);
  1688. delete lpPoints;
  1689. // recover
  1690. DWORD dwSize = GlobalSize(hDib);
  1691. memcpy(lpSrcDIB, lpDIB, dwSize);
  1692. GlobalUnlock(hDib);
  1693. GlobalUnlock(hNewDib);
  1694. if (wBitCount != 24)
  1695. {
  1696. hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);
  1697. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1698. lpDIB = (LPSTR)GlobalLock(hNewDib);
  1699. dwSize = GlobalSize(hNewDib);
  1700. memcpy(lpSrcDIB, lpDIB, dwSize);
  1701. GlobalUnlock(hDIB);
  1702. GlobalUnlock(hNewDib);
  1703. }
  1704. else
  1705. {
  1706. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1707. lpDIB = (LPSTR)GlobalLock(hDib);
  1708. dwSize = GlobalSize(hDib);
  1709. memcpy(lpSrcDIB, lpDIB, dwSize);
  1710. GlobalUnlock(hDIB);
  1711. GlobalUnlock(hDib);
  1712. }
  1713. // cleanup
  1714. GlobalFree(hDib);
  1715. GlobalFree(hNewDib);
  1716. // return
  1717. WaitCursorEnd();
  1718. return TRUE;
  1719. }
  1720. /****************************************************
  1721. WALhDIB()
  1722. 参数:
  1723. hDIB为输入的DIB句柄
  1724. 返回值:
  1725. 成功为TRUE;失败为FALSE
  1726. 说明:
  1727. 本函数实现DIB位图的快速沃尔什-哈达玛变换
  1728. ****************************************************/
  1729. BOOL CImgProcess::WALhDIB(HDIB hDIB)
  1730. {
  1731. if (hDIB == NULL)
  1732. return FALSE;
  1733. // start wait cursor
  1734. WaitCursorBegin();
  1735. HDIB hDib = NULL;
  1736. HDIB hNewDib = NULL;
  1737. // we only convolute 24bpp DIB, so first convert DIB to 24bpp
  1738. WORD wBitCount = DIBBitCount(hDIB);
  1739. if (wBitCount != 24)
  1740. {
  1741. hNewDib = ConvertDIBFormat(hDIB, 24, NULL);
  1742. hDib = CopyHandle(hNewDib);
  1743. }
  1744. else
  1745. {
  1746. hNewDib = CopyHandle(hDIB);
  1747. hDib = CopyHandle(hDIB);
  1748. }
  1749. if (hNewDib == NULL && hDib == NULL)
  1750. {
  1751. WaitCursorEnd();
  1752. return FALSE;
  1753. }
  1754. // process!
  1755. LPSTR lpSrcDIB = (LPSTR)GlobalLock(hDib);
  1756. LPSTR lpDIB = (LPSTR)GlobalLock(hNewDib);
  1757. LPSTR lpInput = FindDIBBits(lpSrcDIB);
  1758. LPSTR lpOutput = FindDIBBits(lpDIB);
  1759. int nWidth = DIBWidth(lpSrcDIB);
  1760. int nHeight = DIBHeight(lpSrcDIB);
  1761. int w=1,h=1,wp=0,hp=0;
  1762. while(w*2<=nWidth)
  1763. {
  1764. w*=2;
  1765. wp++;
  1766. }
  1767. while(h*2<=nHeight)
  1768. {
  1769. h*=2;
  1770. hp++;
  1771. }
  1772. int x,y;
  1773. BYTE *lpPoints=new BYTE[nWidth*nHeight];
  1774. GetPoints(nWidth,nHeight,(BYTE*)lpInput,lpPoints);
  1775. double *f=new double[w*h];
  1776. double *W=new double[w*h];
  1777. for(y=0;y<h;y++)
  1778. {
  1779. for(x=0;x<w;x++)
  1780. {
  1781. f[x+y*w] = lpPoints[x + y * nWidth];
  1782. }
  1783. }
  1784. for(y=0;y<h;y++)
  1785. {
  1786. CMathEx::WALh(f+w*y,W+w*y,wp);
  1787. }
  1788. for(y=0;y<h;y++)
  1789. {
  1790. for(x=0;x<w;x++)
  1791. {
  1792. f[x*h+y]=W[x+w*y];
  1793. }
  1794. }
  1795. for(x=0;x<w;x++)
  1796. {
  1797. CMathEx::WALh(f+x*h,W+x*h,hp);
  1798. }
  1799. double a;
  1800. memset(lpPoints,0,nWidth*nHeight);
  1801. for(y=0;y<h;y++)
  1802. {
  1803. for(x=0;x<w;x++)
  1804. {
  1805. a=fabs(W[x*h+y]*1000);
  1806. if (a>255) a=255;
  1807. lpPoints[x + (nHeight-y-1) * nWidth] = (BYTE)a;
  1808. }
  1809. }
  1810. delete f;
  1811. delete W;
  1812. PutPoints(nWidth,nHeight,(BYTE*)lpOutput,lpPoints);
  1813. delete lpPoints;
  1814. // recover
  1815. DWORD dwSize = GlobalSize(hDib);
  1816. memcpy(lpSrcDIB, lpDIB, dwSize);
  1817. GlobalUnlock(hDib);
  1818. GlobalUnlock(hNewDib);
  1819. if (wBitCount != 24)
  1820. {
  1821. hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL);
  1822. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1823. lpDIB = (LPSTR)GlobalLock(hNewDib);
  1824. dwSize = GlobalSize(hNewDib);
  1825. memcpy(lpSrcDIB, lpDIB, dwSize);
  1826. GlobalUnlock(hDIB);
  1827. GlobalUnlock(hNewDib);
  1828. }
  1829. else
  1830. {
  1831. lpSrcDIB = (LPSTR)GlobalLock(hDIB);
  1832. lpDIB = (LPSTR)GlobalLock(hDib);
  1833. dwSize = GlobalSize(hDib);
  1834. memcpy(lpSrcDIB, lpDIB, dwSize);
  1835. GlobalUnlock(hDIB);
  1836. GlobalUnlock(hDib);
  1837. }
  1838. // cleanup
  1839. GlobalFree(hDib);
  1840. GlobalFree(hNewDib);
  1841. // return
  1842. WaitCursorEnd();
  1843. return TRUE;
  1844. }