DIB.cpp
上传用户:sdsuchuang
上传日期:2013-01-12
资源大小:2228k
文件大小:18k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // DIB.cpp: implementation of the DIB class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "DIB.h"
  6. #include"math.h"
  7. #include "LikelyHood.h"
  8. #define WIDTHBYTES(bits)  ((bits+31)/32*4)
  9. #define RECTWIDTH(x) (x->right-x->left)
  10. #define RECTHEIGHT(x) (x->bottom-x->top)
  11. #define THRESHOLDCONTRAST  40
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[]=__FILE__;
  15. #define new DEBUG_NEW
  16. #endif
  17. #define PI 3.1415926
  18. extern int locax,locay;
  19. #define m_WIDTH 600
  20. #define m_HEIGHT 600
  21. //////////////////////////////////////////////////////////////////////
  22. // Construction/Destruction
  23. /////////////////////////////////////////////////////////////////////
  24. HDIB DIB::ReadDIBFile(HANDLE hFile)
  25. {
  26. BITMAPFILEHEADER bmfHeader;
  27. DWORD dwBitsSize;
  28. HANDLE hDIB;
  29. HANDLE hDIBtmp;
  30. LPBITMAPINFOHEADER lpbi;
  31. DWORD dwRead;
  32.     //得到文件大小
  33. dwBitsSize = GetFileSize(hFile,NULL);
  34. hDIB =  GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));
  35. if(!hDIB)
  36. return NULL;
  37. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  38. if(!lpbi)
  39. {
  40. GlobalFree(hDIB);
  41. return NULL;
  42. }
  43. if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
  44. goto ErrExit;
  45. if(sizeof(BITMAPFILEHEADER)!=dwRead)//读取文件出错
  46. goto ErrExit;
  47. if(bmfHeader.bfType != 0x4d42)//文件类型不匹配
  48. goto ErrExit;
  49. if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
  50. goto ErrExit;
  51. if(sizeof(BITMAPINFOHEADER)!= dwRead)//读取数据出错
  52. goto ErrExit;
  53. GlobalUnlock(hDIB);
  54. if(lpbi->biSizeImage==0)
  55. lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;
  56. hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
  57. if(!hDIBtmp)
  58. goto ErrExitNoUnlock;
  59. else
  60. hDIB = hDIBtmp;
  61. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  62. //根据情况设定文件指针
  63. if(bmfHeader.bfOffBits != 0L)
  64. SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
  65.     //读取文件的象素颜色数据
  66. if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
  67. goto OKExit;
  68. ErrExit:
  69. GlobalUnlock(hDIB);
  70. ErrExitNoUnlock:
  71. GlobalFree(hDIB); //释放内存
  72. return NULL;
  73. OKExit:
  74. GlobalUnlock(hDIB);
  75. return hDIB;
  76. }
  77. HDIB DIB::LoadDIB(LPCTSTR lpFileName)
  78. {
  79. HANDLE hDIB;
  80. HANDLE hFile;
  81. //创建文件句柄
  82. if((hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
  83. {  
  84. //读取数据
  85. hDIB = ReadDIBFile(hFile);
  86. //关闭文件句柄
  87. CloseHandle(hFile);
  88. return hDIB;
  89. }
  90. return NULL;
  91. }
  92. BOOL DIB::PaintDIBTrue(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
  93. {
  94. LPBYTE lpDIBHdr;
  95. LPBYTE lpDIBBits;
  96. BOOL bSuccess = FALSE;
  97. if(!hDIB)
  98. return FALSE;
  99. lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
  100. lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
  101. bSuccess = StretchDIBits(hDC,lpDCRect->left,
  102.  lpDCRect->top,
  103.  RECTWIDTH(lpDCRect),
  104.  RECTHEIGHT(lpDCRect),
  105.  lpDIBRect->left,
  106.  ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
  107.  RECTWIDTH(lpDIBRect),
  108.  RECTHEIGHT(lpDIBRect),
  109.  lpDIBBits,
  110.  (LPBITMAPINFO)lpDIBHdr,
  111.  DIB_RGB_COLORS,
  112.  SRCCOPY);
  113. GlobalUnlock(hDIB);
  114. return bSuccess;
  115. }
  116. BOOL DIB::PaintDIBTrue1(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
  117. {
  118. LPBYTE lpDIBHdr;
  119. LPBYTE lpDIBBits;
  120. BOOL bSuccess = FALSE;
  121. if(!hDIB)
  122. return FALSE;
  123. lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
  124. lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
  125. bSuccess = StretchDIBits(hDC,lpDCRect->left,
  126.  lpDCRect->top,
  127.  RECTWIDTH(lpDCRect),
  128.  RECTHEIGHT(lpDCRect),
  129.  lpDIBRect->left,
  130.  ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
  131.  RECTWIDTH(lpDIBRect),
  132.  RECTHEIGHT(lpDIBRect),
  133.  lpDIBBits,
  134.  (LPBITMAPINFO)lpDIBHdr,
  135.  DIB_RGB_COLORS,
  136.  SRCCOPY);
  137. GlobalUnlock(hDIB);
  138. return bSuccess;
  139. }
  140. WORD DIB::BytePerLine(HANDLE hDIB)
  141. {
  142. WORD i;
  143. LPBITMAPINFOHEADER lpbi;
  144. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  145. i = WIDTHBYTES((lpbi->biWidth)*24);
  146. GlobalUnlock(hDIB);
  147. return i;
  148. }
  149. LPBYTE  DIB::FindDIBBits(HANDLE hDIB)
  150. {
  151. LPBYTE lpDIB,lpDIBtmp;
  152. LPBITMAPINFOHEADER lpbi;
  153. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  154. lpDIBtmp = (LPBYTE)lpbi;
  155. lpDIB = lpDIBtmp + sizeof(BITMAPINFOHEADER);
  156. GlobalUnlock(hDIB);
  157. return lpDIB;
  158. }
  159. long DIB::PixelOffset(int i,int j,WORD wBytePerLine)
  160. {
  161. long   Offset;
  162. Offset = i*wBytePerLine + j*3;
  163. return Offset;
  164. }
  165. DIB::DIB()
  166. {
  167. for(int i=0;i<ImgRange; i++)
  168. for (int j=0; j<ImgRange; j++)
  169. this->lab[i][j] = false;
  170. m_pDib=NULL;
  171. }
  172. DIB::~DIB()
  173. {
  174. }
  175. BOOL DIB:: SaveDIB(HANDLE hDib, CFile& file)
  176. {
  177. // Bitmap文件头
  178. BITMAPFILEHEADER bmfHdr;
  179. // 指向BITMAPINFOHEADER的指针
  180. LPBITMAPINFOHEADER lpBI;
  181. // DIB大小
  182. DWORD dwDIBSize =0;
  183. if (hDib == NULL)
  184. {
  185. // 如果DIB为空,返回FALSE
  186. return FALSE;
  187. }
  188. // 读取BITMAPINFO结构,并锁定
  189. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  190. if (lpBI == NULL)
  191. {
  192. // 为空,返回FALSE
  193. return FALSE;
  194. }
  195. // 判断是否是WIN3.0 DIB
  196. // if (!IS_WIN30_DIB(lpBI))
  197. // {
  198. // 不支持其它类型的DIB保存
  199. // 解除锁定
  200. // ::GlobalUnlock((HGLOBAL) hDib);
  201. // 返回FALSE
  202. // return FALSE;
  203. // }
  204. // 填充文件头
  205. // 文件类型"BM"
  206. bmfHdr.bfType =  0x4d42; //DIB_HEADER_MARKER;
  207. // 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
  208. // 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
  209. // 文件头大小+颜色表大小
  210. // (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
  211. // dwDIBSize = *(LPDWORD)lpBI; //+ ::PaletteSize((LPSTR)lpBI);
  212. dwDIBSize = sizeof(BITMAPINFOHEADER);//+lpBI->biSizeImage;
  213. // 计算图像大小
  214. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  215. {
  216. // 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
  217. dwDIBSize += lpBI->biSizeImage;
  218. }
  219. else
  220. {
  221. // 象素的大小
  222. DWORD dwBmBitsSize;
  223. // 大小为Width * Height
  224. dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*24) * lpBI->biHeight;
  225. // 计算出DIB真正的大小
  226. dwDIBSize += dwBmBitsSize;
  227. // 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
  228. lpBI->biSizeImage = dwBmBitsSize;
  229. }
  230. // 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
  231. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  232. // 两个保留字
  233. bmfHdr.bfReserved1 = 0;
  234. bmfHdr.bfReserved2 = 0;
  235. // 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
  236. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
  237.  // + PaletteSize((LPSTR)lpBI);
  238. // 尝试写文件
  239. // TRY
  240. {
  241. // 写文件头
  242. file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  243. // 写DIB头和象素
  244. file.WriteHuge(lpBI, dwDIBSize);
  245. }
  246. // CATCH (CFileException, e)
  247. // {
  248. // 解除锁定
  249. // ::GlobalUnlock((HGLOBAL) hDib);
  250. // 抛出异常
  251. /// THROW_LAST();
  252. // }
  253. // END_CATCH
  254. // 解除锁定
  255. ::GlobalUnlock((HGLOBAL) hDib);
  256. // 返回TRUE
  257. return TRUE;
  258. }
  259. HANDLE DIB::CopyHandle( HANDLE hSrc)
  260. {
  261. HANDLE hDst;
  262. LPBITMAPINFOHEADER lpbi;
  263. int width,height;
  264. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hSrc);
  265. width = lpbi->biWidth;
  266. height = lpbi->biHeight;
  267. hDst = GlobalAlloc(GMEM_MOVEABLE,lpbi->biSize+lpbi->biSizeImage);
  268. if(!hDst)
  269. return NULL;
  270. LPBYTE lpDest;
  271. lpDest = (LPBYTE)GlobalLock(hDst);
  272. memcpy(lpDest,(LPBYTE)lpbi,lpbi->biSize+lpbi->biSizeImage);
  273. GlobalUnlock(hSrc);
  274. GlobalUnlock(hDst);
  275. return hDst;
  276. }
  277. BYTE * DIB::GetBits()
  278. {
  279. //the size of the color map is determined by the number
  280. //of RGBQUAD structures presend.
  281. //it also depends on the bit_depth of the Dib
  282. DWORD dwNumColors,dwColorTableSize;
  283. BITMAPINFOHEADER *lpDib=(BITMAPINFOHEADER *)m_pDib;
  284.           
  285. WORD wBitCount=lpDib->biBitCount;
  286. if(lpDib->biSize>=36)
  287. dwNumColors=lpDib->biClrUsed;
  288. else
  289. dwNumColors=0;
  290.       
  291. if(dwNumColors==0)
  292. {
  293. if(wBitCount!=24)
  294. dwNumColors=1L<<wBitCount;
  295. else 
  296. dwNumColors=0;
  297. }
  298. dwColorTableSize=dwNumColors*sizeof(RGBQUAD);
  299. return m_pDib+lpDib->biSize+dwColorTableSize;
  300. }
  301. int DIB::GetBiBitCount()
  302. {
  303. if(m_pDib!=NULL)
  304. return ((BITMAPINFOHEADER *)m_pDib)->biBitCount; 
  305. return 0;
  306. }
  307. LONG DIB::GetWidth()
  308. {
  309. return ((BITMAPINFOHEADER *)m_pDib)->biWidth;
  310. }
  311. LONG DIB::GetHeight()
  312. {
  313. return ((BITMAPINFOHEADER *)m_pDib)->biHeight;
  314. }
  315. //////////////////////光线补偿//////////////////////////////
  316. ////////////////////////////////////////////////////////////
  317. BOOL DIB::LightingCompensate(HANDLE hDIB)
  318. {
  319. if(!hDIB)
  320. return FALSE;
  321. LPBITMAPINFOHEADER lpbi;
  322. int width,height;
  323. LPBYTE lpData;
  324. WORD wBytesPerLine;
  325. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  326. //得到图片宽和高
  327. width = lpbi->biWidth;
  328. height = lpbi->biHeight;
  329. //得到图片数据区
  330. lpData = this->FindDIBBits(hDIB);
  331. //得到图片每行的象素所占字节个数
  332. wBytesPerLine = this->BytePerLine(hDIB);
  333. //比例系数
  334. const float thresholdco = 0.05;
  335. //象素个数的临界常数
  336. const int thresholdnum = 100;
  337. //灰度级数组
  338. int histogram[256];
  339. for(int i =0;i<256;i++)
  340. histogram[i] = 0;
  341. //对于过于小的图片的判断
  342. if(width*height*thresholdco < thresholdnum)
  343. return false;
  344. int colorr,colorg,colorb;
  345. long lOffset;
  346. //考察整个图片
  347. for( i=0;i<height;i++)
  348. for(int j=0;j<width;j++)
  349. {
  350. //得到象素数据的偏移
  351. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  352. //得到rgb值
  353. colorb = *(lpData+lOffset++);
  354. colorg = *(lpData+lOffset++);
  355. colorr = *(lpData+lOffset++);
  356. //计算灰度值
  357. int gray = (colorr * 299 + colorg * 587 + colorb * 114)/1000;
  358. histogram[gray]++;
  359. }
  360. int calnum =0;
  361. int total = width*height;
  362. int num;
  363. //下面的循环得到满足系数thresholdco的临界灰度级
  364. for(i =0;i<256;i++)
  365. {
  366. if((float)calnum/total < thresholdco)
  367. {
  368. calnum+= histogram[255-i];
  369. num = i;
  370. }
  371. else
  372. break;
  373. }
  374. int averagegray = 0;
  375. calnum =0;
  376. //得到满足条件的象素总的灰度值
  377. for(i = 255;i>=255-num;i--)
  378. {
  379. averagegray += histogram[i]*i;
  380. calnum += histogram[i];
  381. }
  382. averagegray /=calnum;
  383. //得到光线补偿的系数
  384. float co = 255.0/(float)averagegray;
  385. //下面的循环对图象进行光线补偿
  386. for(i =0;i<height;i++)
  387. for(int j=0;j<width;j++)
  388. {
  389. //得到数据偏移
  390. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  391. //得到蓝色分量
  392. colorb = *(lpData+lOffset);
  393. //调整
  394. colorb *=co;
  395. //临界判断
  396. if(colorb >255)
  397. colorb = 255;
  398. //保存
  399. *(lpData+lOffset) = colorb;
  400. //绿色分量
  401. colorb = *(lpData+lOffset+1);
  402. colorb *=co;
  403. if(colorb >255)
  404. colorb = 255;
  405. *(lpData+lOffset+1) = colorb;
  406. //红色分量
  407. colorb = *(lpData+lOffset+2);
  408. colorb *=co;
  409. if(colorb >255)
  410. colorb = 255;
  411. *(lpData+lOffset+2) = colorb;
  412. }
  413. return TRUE;
  414. }
  415. //////////////////////////////////////膨胀////////////////////////////////////////////
  416. /////////////////////////////////////////////////////////////////////////////////////
  417. void DIB::Dilation(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
  418. {
  419. LPBITMAPINFOHEADER lpbi;
  420. int height;
  421. int width;
  422. WORD wBytesPerLine;
  423. LPBYTE lpData;
  424. LPBYTE lpTemp;
  425. long lOffset;
  426. //得到图象的基本信息
  427. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  428. height = m_top;
  429. width = m_right;
  430. wBytesPerLine = this->BytePerLine(hDIB);
  431. lpData = this->FindDIBBits(hDIB);
  432. //申请一块和数据区大小相同的内存
  433. lpTemp = (LPBYTE) new BYTE[wBytesPerLine * height];
  434. long lOffsetJudge;
  435. for (int i=1+m_bottom; i<height-1; i++)
  436. for (int j=1+m_left; j<width-1; j++)
  437. {
  438. lOffset = this->PixelOffset(i, j, wBytesPerLine);
  439. //如果当前点为白色,接着循环
  440. if(*(lpData + lOffset) == 255)
  441. {
  442. *(lpTemp + lOffset++) = 255;
  443. *(lpTemp + lOffset++) = 255;
  444. *(lpTemp + lOffset++) = 255;
  445. continue;
  446. }
  447. //否则考察上下左右四个点
  448. else
  449. {
  450. lOffsetJudge = this->PixelOffset(i-1, j, wBytesPerLine);
  451. //如果上面的点为白色
  452. if(*(lpData + lOffsetJudge) == 255)
  453. { //设置为白色,并继续循环
  454. *(lpTemp + lOffset++) = 255;
  455. *(lpTemp + lOffset++) = 255;
  456. *(lpTemp + lOffset++) = 255;
  457. continue;
  458. }
  459. //考察下面的点
  460. lOffsetJudge = this->PixelOffset(i+1,j, wBytesPerLine);
  461. if(*(lpData + lOffsetJudge) == 255)
  462. {
  463. *(lpTemp + lOffset++) = 255;
  464. *(lpTemp + lOffset++) = 255;
  465. *(lpTemp + lOffset++) = 255;
  466. continue;
  467. }
  468. //考察左边的点
  469. lOffsetJudge = this->PixelOffset(i,j-1, wBytesPerLine);
  470. if(*(lpData + lOffsetJudge) == 255)
  471. {
  472. *(lpTemp + lOffset++) = 255;
  473. *(lpTemp + lOffset++) = 255;
  474. *(lpTemp + lOffset++) = 255;
  475. continue;
  476. }
  477. //考察右边的点
  478. lOffsetJudge = this->PixelOffset(i,j+1, wBytesPerLine);
  479. if(*(lpData + lOffsetJudge) == 255)
  480. {
  481. *(lpTemp + lOffset++) = 255;
  482. *(lpTemp + lOffset++) = 255;
  483. *(lpTemp + lOffset++) = 255;
  484. continue;
  485. }
  486. //如果上下左右都是黑色点,则把暂时区域的点设置为黑色
  487. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  488. *(lpTemp + lOffset++) = 0;
  489. *(lpTemp + lOffset++) = 0;
  490. *(lpTemp + lOffset++) = 0;
  491. }
  492. }
  493. //处理图象四周的点,设置为黑色
  494. for(i=m_bottom; i<height; i++)
  495. {
  496. lOffset = this->PixelOffset(i, 0, wBytesPerLine);
  497. {
  498. *(lpTemp + lOffset++) = 0;
  499. *(lpTemp + lOffset++) = 0;
  500. *(lpTemp + lOffset++) = 0;
  501. }
  502. }
  503. for(i=m_bottom; i<height; i++)
  504. {
  505. lOffset = this->PixelOffset(i, width-1, wBytesPerLine);
  506. {
  507. *(lpTemp + lOffset++) = 0;
  508. *(lpTemp + lOffset++) = 0;
  509. *(lpTemp + lOffset++) = 0;
  510. }
  511. }
  512. for(i=m_left; i<width; i++)
  513. {
  514. lOffset = this->PixelOffset(0, i, wBytesPerLine);
  515. {
  516. *(lpTemp + lOffset++) = 0;
  517. *(lpTemp + lOffset++) = 0;
  518. *(lpTemp + lOffset++) = 0;
  519. }
  520. }
  521. for(i=m_left; i<width; i++)
  522. {
  523. lOffset = this->PixelOffset(height-1, i, wBytesPerLine);
  524. {
  525. *(lpTemp + lOffset++) = 0;
  526. *(lpTemp + lOffset++) = 0;
  527. *(lpTemp + lOffset++) = 0;
  528. }
  529. }
  530. //把暂时区域的点拷贝到原句柄区域下面
  531. memcpy(lpData, lpTemp, wBytesPerLine*height);
  532. delete [] lpTemp;
  533. GlobalUnlock(hDIB);
  534. }
  535. ////////////////////////////////////////////////////////////////////////////////
  536. /////////////////////////////////////腐蚀///////////////////////////////////////
  537. void DIB::Erasion(HANDLE hDIB,int m_top,int m_bottom,int m_left,int m_right)
  538. {
  539. LPBITMAPINFOHEADER lpbi;
  540. LPBYTE lpData;
  541. WORD wBytesPerLine;
  542. long lOffset;
  543. long lOffsetJudge;
  544. int height;
  545. int width;
  546. //得到基本数据
  547. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  548. height = m_top;
  549. width = m_right;
  550. wBytesPerLine = BytePerLine(hDIB);
  551. lpData = FindDIBBits(hDIB);
  552. HANDLE hTempDIB;
  553. LPBYTE lpTemp;
  554. //申请同样大小的内存
  555. hTempDIB =   GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER) + wBytesPerLine*height));
  556. //判断内存情况
  557. if(!hTempDIB)
  558. {
  559. GlobalFree(hTempDIB);
  560. GlobalFree(hDIB);
  561. return;
  562. }
  563. lpTemp = (LPBYTE)GlobalLock(hTempDIB);
  564. lpTemp+= sizeof(BITMAPINFOHEADER);
  565. //下面的循环实现腐蚀功能
  566. for (int i=1+m_bottom; i<height-1; i++)
  567. for (int j=1+m_left; j<width-1; j++)
  568. {
  569. lOffset = PixelOffset(i,j,wBytesPerLine);
  570. //如果为白色点
  571. if (*(lpData+lOffset) == 255)
  572. {
  573. //考察上面的点
  574. lOffsetJudge = PixelOffset(i-1, j, wBytesPerLine);
  575. //如果是黑色就把原来的点设置为黑色,并接着循环
  576. if (*(lpData + lOffsetJudge) ==0)
  577. {
  578. *(lpTemp + lOffset++) = 0;
  579. *(lpTemp + lOffset++) = 0;
  580. *(lpTemp + lOffset++) = 0;
  581. continue;
  582. }
  583. //考察下面的点
  584. lOffsetJudge = PixelOffset(i+1, j, wBytesPerLine);
  585. if (*(lpData + lOffsetJudge) ==0)
  586. {
  587. *(lpTemp + lOffset++) = 0;
  588. *(lpTemp + lOffset++) = 0;
  589. *(lpTemp + lOffset++) = 0;
  590. continue;
  591. }
  592. //左面的点
  593. lOffsetJudge = PixelOffset(i, j-1, wBytesPerLine);
  594. if (*(lpData + lOffsetJudge) ==0)
  595. {
  596. *(lpTemp + lOffset++) = 0;
  597. *(lpTemp + lOffset++) = 0;
  598. *(lpTemp + lOffset++) = 0;
  599. continue;
  600. }
  601. //右面的点
  602. lOffsetJudge = PixelOffset(i, j+1, wBytesPerLine);
  603. if (*(lpData + lOffsetJudge) ==0)
  604. {
  605. *(lpTemp + lOffset++) = 0;
  606. *(lpTemp + lOffset++) = 0;
  607. *(lpTemp + lOffset++) = 0;
  608. continue;
  609. }
  610. //如果上下左右四个点都是白色,则设置为白色
  611. lOffset = this->PixelOffset(i, j, wBytesPerLine);
  612. *(lpTemp + lOffset)   = 255;
  613. *(lpTemp + lOffset+1) = 255;
  614. *(lpTemp + lOffset+2) = 255;
  615. }
  616. //如果当前点为黑色,则在暂时的目标区域中设置为黑色
  617. else
  618. {
  619. *(lpTemp + lOffset)   = 0;
  620. *(lpTemp + lOffset+1) = 0;
  621. *(lpTemp + lOffset+2) = 0;
  622. }
  623. }
  624. //把图象周边的点全部设置为黑色
  625. for(i=m_bottom; i<height; i++)
  626. {
  627. lOffset = PixelOffset(i, 0, wBytesPerLine);
  628. *(lpTemp + lOffset)   = 0;
  629. *(lpTemp + lOffset+1) = 0;
  630. *(lpTemp + lOffset+2) = 0;
  631. }
  632. for(i=m_bottom; i<height; i++)
  633. {
  634. lOffset = PixelOffset(i, width-1, wBytesPerLine);
  635. *(lpTemp + lOffset)   = 0;
  636. *(lpTemp + lOffset+1) = 0;
  637. *(lpTemp + lOffset+2) = 0;
  638. }
  639. for (i=m_left; i<width; i++)
  640. {
  641. lOffset = PixelOffset(0, i, wBytesPerLine);
  642. *(lpTemp + lOffset)   = 0;
  643. *(lpTemp + lOffset+1) = 0;
  644. *(lpTemp + lOffset+2) = 0;
  645. }
  646. for (i=m_left; i<width; i++)
  647. {
  648. lOffset = PixelOffset(height-1, i, wBytesPerLine);
  649. *(lpTemp + lOffset)   = 0;
  650. *(lpTemp + lOffset+1) = 0;
  651. *(lpTemp + lOffset+2) = 0;
  652. }
  653. //把暂时区域的数值拷贝到原来的句柄下面
  654. memcpy(lpData,lpTemp,wBytesPerLine*height);
  655. GlobalUnlock(hDIB);
  656. GlobalUnlock(hTempDIB);
  657. GlobalFree(hTempDIB);
  658. }