DIB.cpp
上传用户:seppec
上传日期:2010-02-09
资源大小:2347k
文件大小:33k
源码类别:

2D图形编程

开发平台:

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. #define WIDTHBYTES(bits)  ((bits+31)/32*4)
  8. #define RECTWIDTH(x) (x->right-x->left)
  9. #define RECTHEIGHT(x) (x->bottom-x->top)
  10. #define THRESHOLDCONTRAST  40
  11. #ifdef _DEBUG
  12. #undef THIS_FILE
  13. static char THIS_FILE[]=__FILE__;
  14. #define new DEBUG_NEW
  15. #endif
  16. #define PI 3.1415926
  17. extern int locax,locay;
  18. #define m_WIDTH 600
  19. #define m_HEIGHT 600
  20. //////////////////////////////////////////////////////////////////////
  21. // Construction/Destruction
  22. /////////////////////////////////////////////////////////////////////
  23. HDIB DIB::ReadDIBFile(HANDLE hFile)
  24. {
  25. BITMAPFILEHEADER bmfHeader;
  26. DWORD dwBitsSize;
  27. HANDLE hDIB;
  28. HANDLE hDIBtmp;
  29. LPBITMAPINFOHEADER lpbi;
  30. DWORD dwRead;
  31.     //得到文件大小
  32. dwBitsSize = GetFileSize(hFile,NULL);
  33. hDIB =  GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)));
  34. if(!hDIB)
  35. return NULL;
  36. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  37. if(!lpbi)
  38. {
  39. GlobalFree(hDIB);
  40. return NULL;
  41. }
  42. if(!ReadFile(hFile,(LPBYTE)&bmfHeader,sizeof(BITMAPFILEHEADER),&dwRead,NULL))
  43. goto ErrExit;
  44. if(sizeof(BITMAPFILEHEADER)!=dwRead)//读取文件出错
  45. goto ErrExit;
  46. if(bmfHeader.bfType != 0x4d42)//文件类型不匹配
  47. goto ErrExit;
  48. if(!ReadFile(hFile,(LPBYTE)lpbi,sizeof(BITMAPINFOHEADER),&dwRead,NULL))
  49. goto ErrExit;
  50. if(sizeof(BITMAPINFOHEADER)!= dwRead)//读取数据出错
  51. goto ErrExit;
  52. GlobalUnlock(hDIB);
  53. if(lpbi->biSizeImage==0)
  54. lpbi->biSizeImage = (this->BytePerLine(hDIB))*lpbi->biHeight;
  55. hDIBtmp = GlobalReAlloc(hDIB,lpbi->biSize+lpbi->biSizeImage,0);
  56. if(!hDIBtmp)
  57. goto ErrExitNoUnlock;
  58. else
  59. hDIB = hDIBtmp;
  60. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  61. //根据情况设定文件指针
  62. if(bmfHeader.bfOffBits != 0L)
  63. SetFilePointer(hFile,bmfHeader.bfOffBits,NULL,FILE_BEGIN);
  64.     //读取文件的象素颜色数据
  65. if(ReadFile(hFile,(LPBYTE)lpbi+lpbi->biSize,lpbi->biSizeImage,&dwRead,NULL))
  66. goto OKExit;
  67. ErrExit:
  68. GlobalUnlock(hDIB);
  69. ErrExitNoUnlock:
  70. GlobalFree(hDIB); //释放内存
  71. return NULL;
  72. OKExit:
  73. GlobalUnlock(hDIB);
  74. return hDIB;
  75. }
  76. HDIB DIB::LoadDIB(LPCTSTR lpFileName)
  77. {
  78. HANDLE hDIB;
  79. HANDLE hFile;
  80. //创建文件句柄
  81. if((hFile = CreateFile(lpFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL))!= INVALID_HANDLE_VALUE)
  82. {  
  83. //读取数据
  84. hDIB = ReadDIBFile(hFile);
  85. //关闭文件句柄
  86. CloseHandle(hFile);
  87. return hDIB;
  88. }
  89. return NULL;
  90. }
  91. BOOL DIB::PaintDIBTrue(HDC hDC,LPRECT lpDCRect,HANDLE hDIB,LPRECT lpDIBRect ,DWORD dwRop)
  92. {
  93. LPBYTE lpDIBHdr;
  94. LPBYTE lpDIBBits;
  95. BOOL bSuccess = FALSE;
  96. if(!hDIB)
  97. return FALSE;
  98. lpDIBHdr = (LPBYTE)GlobalLock(hDIB);
  99. lpDIBBits = lpDIBHdr + sizeof(BITMAPINFOHEADER);
  100. bSuccess = StretchDIBits(hDC,lpDCRect->left,
  101.  lpDCRect->top,
  102.  RECTWIDTH(lpDCRect),
  103.  RECTHEIGHT(lpDCRect),
  104.  lpDIBRect->left,
  105.  ((LPBITMAPINFOHEADER)lpDIBHdr)->biHeight-lpDIBRect->top-RECTHEIGHT(lpDIBRect),
  106.  RECTWIDTH(lpDIBRect),
  107.  RECTHEIGHT(lpDIBRect),
  108.  lpDIBBits,
  109.  (LPBITMAPINFO)lpDIBHdr,
  110.  DIB_RGB_COLORS,
  111.  SRCCOPY);
  112. GlobalUnlock(hDIB);
  113. return bSuccess;
  114. }
  115. WORD DIB::BytePerLine(HANDLE hDIB)
  116. {
  117. WORD i;
  118. LPBITMAPINFOHEADER lpbi;
  119. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  120. i = WIDTHBYTES((lpbi->biWidth)*24);
  121. GlobalUnlock(hDIB);
  122. return i;
  123. }
  124. //函数实现图片从彩色到黑白的转换
  125. HDIB DIB::ToGray(HANDLE hDIB)
  126. {
  127. HDIB hNewDIB = NULL;
  128. LPBITMAPINFOHEADER lpSrc,lpDest;
  129. LPBYTE lpS,lpD;
  130. DWORD dwBytesPerLine;
  131. DWORD dwImgSize;
  132. WORD wBytesPerLine;
  133. unsigned i ,j,height,width;
  134. if(!hDIB)
  135. return NULL;
  136. lpSrc = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  137. dwBytesPerLine = WIDTHBYTES(24*(lpSrc->biWidth));
  138. dwImgSize = lpSrc->biHeight * dwBytesPerLine;
  139. //申请新的内存,大小等于原来图象的大小
  140. hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+dwImgSize);
  141. lpDest = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB);
  142. //保存图片的长宽、颜色深度等信息
  143. memcpy((void*)lpDest,(void*)lpSrc,sizeof(BITMAPINFOHEADER));
  144. DWORD dwSBytesPerLine;
  145. dwSBytesPerLine = (24*(lpSrc->biWidth)+31)/32*4;
  146. height = lpDest->biHeight;
  147. width = lpDest->biWidth;
  148. lpS = (LPBYTE)lpSrc;
  149. wBytesPerLine = this->BytePerLine(hDIB);
  150. lpD = (LPBYTE)lpDest;
  151. lpS = lpS + sizeof(BITMAPINFOHEADER);
  152. lpD = lpD + sizeof(BITMAPINFOHEADER);
  153. unsigned  r , g ,b,gray ;
  154. //扫描整个图片,实现灰度化
  155. for(i = 0 ;i<height; i++)
  156. {
  157. for(j = 0 ;j<(unsigned )lpDest->biWidth;j++)
  158. {
  159.         //获得原来图片的颜色值
  160. r = *(lpS++);
  161. g = *(lpS++);
  162. b  = *(lpS++);
  163. //计算灰度值
  164. gray = (g*50+r*39+b*11)/100;
  165. //保存灰度值到目标图片
  166. *(lpD++)=gray;
  167. *(lpD++) = gray;
  168. *(lpD++) = gray;
  169. }
  170. //处理四字节对齐问题
  171. unsigned  k ;
  172. for(k=0;k<dwSBytesPerLine-lpSrc->biWidth*3;k++)
  173. {
  174. lpS++;
  175. lpD++;
  176. }
  177. }
  178. GlobalUnlock(hDIB);
  179. GlobalUnlock(hNewDIB);
  180.     return hNewDIB;
  181. }
  182. LPBYTE  DIB::FindDIBBits(HANDLE hDIB)
  183. {
  184. LPBYTE lpDIB,lpDIBtmp;
  185. LPBITMAPINFOHEADER lpbi;
  186. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  187. lpDIBtmp = (LPBYTE)lpbi;
  188. lpDIB = lpDIBtmp + sizeof(BITMAPINFOHEADER);
  189. GlobalUnlock(hDIB);
  190. return lpDIB;
  191. }
  192. long DIB::PixelOffset(int i,int j,WORD wBytePerLine)
  193. {
  194. long   Offset;
  195. Offset = i*wBytePerLine + j*3;
  196. return Offset;
  197. }
  198. //函数实现对图片的中值滤波处理
  199. void DIB::MedianFilterDIB(HANDLE hDIB)
  200. {
  201. HDIB hNewDIB;
  202. LPBYTE  lpS,lpD;
  203. LPBITMAPINFOHEADER lpbi;
  204. int r,g,b;
  205. DWORD width,height;
  206. WORD wBytesPerLine;
  207. long lOffset;
  208. if(!hDIB)
  209. return;
  210. SetCursor(LoadCursor(NULL,IDC_WAIT));
  211. wBytesPerLine = this->BytePerLine(hDIB);
  212. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  213. width = lpbi->biWidth;
  214. height = lpbi->biHeight;
  215.  //申请一块新的内存
  216. hNewDIB = GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+lpbi->biSizeImage);
  217. lpD = (LPBYTE)GlobalLock(hNewDIB);
  218. lpS = (LPBYTE)lpbi;
  219. memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
  220. lpS = lpS+sizeof(BITMAPINFOHEADER);
  221. lpD = lpD+sizeof(BITMAPINFOHEADER);
  222. //扫描整个图片
  223. for(WORD i=1;i<height-1;i++)
  224. for(WORD j=1;j<width-1;j++)
  225. { //中值滤波
  226. this->DoMedianFilterDIB(&r,&g,&b,i,j,wBytesPerLine,lpS);
  227. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  228. *(lpD+lOffset++) = r;
  229. *(lpD+lOffset++) = g;
  230. *(lpD+lOffset)   = b;
  231. }
  232. //把信息拷贝回原来的句柄
  233. for( i = 1;i<height-1;i++)
  234. for(WORD j = 1;j<width-1;j++)
  235. {
  236. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  237. //活得新图片的颜色
  238. int color1 = *(lpD+lOffset++);
  239. int color2 = *(lpD+lOffset++);
  240. int color3 = *(lpD+lOffset++);
  241. //拷贝到原来图片中
  242. *(lpS+lOffset++) = color1;
  243. *(lpS+lOffset++) = color2;
  244. *(lpS+lOffset++) = color3;
  245. }
  246. SetCursor(LoadCursor(NULL,IDC_ARROW));
  247. GlobalUnlock(hDIB);
  248. GlobalUnlock(hNewDIB);
  249. GlobalFree(hNewDIB);
  250. }
  251. void DIB::DoMedianFilterDIB(int *r,int *g,int*b,WORD i,WORD j,WORD wBytesPerLine,LPBYTE lpDIBBits)
  252. {
  253. long lOffset;
  254. int rgb[9][3];
  255. //把八个方位和当前位置得rgb值保存到数组rgb[9][3]中
  256. lOffset = this->PixelOffset( i-1, j-1, wBytesPerLine); 
  257. rgb[0][0] = *(lpDIBBits+lOffset++);
  258. rgb[0][1] = *(lpDIBBits+lOffset++);
  259. rgb[0][2] = *(lpDIBBits+lOffset++);
  260. lOffset = this->PixelOffset( i-1, j, wBytesPerLine);
  261. rgb[1][0] = *(lpDIBBits+lOffset++);
  262. rgb[1][1] = *(lpDIBBits+lOffset++);
  263. rgb[1][2] = *(lpDIBBits+lOffset++);
  264. lOffset = this->PixelOffset( i-1, j+1, wBytesPerLine);
  265. rgb[2][0] = *(lpDIBBits+lOffset++);
  266. rgb[2][1] = *(lpDIBBits+lOffset++);
  267. rgb[2][2] = *(lpDIBBits+lOffset++);
  268. lOffset = this->PixelOffset( i, j-1, wBytesPerLine);
  269. rgb[3][0] = *(lpDIBBits+lOffset++);
  270. rgb[3][1] = *(lpDIBBits+lOffset++);
  271. rgb[3][2] = *(lpDIBBits+lOffset++);
  272. lOffset = this->PixelOffset( i, j, wBytesPerLine);
  273. rgb[4][0] = *(lpDIBBits+lOffset++);
  274. rgb[4][1] = *(lpDIBBits+lOffset++);
  275. rgb[4][2] = *(lpDIBBits+lOffset++);
  276. lOffset = this->PixelOffset( i, j+1, wBytesPerLine);
  277. rgb[5][0] = *(lpDIBBits+lOffset++);
  278. rgb[5][1] = *(lpDIBBits+lOffset++);
  279. rgb[5][2] = *(lpDIBBits+lOffset++);
  280. lOffset = this->PixelOffset( i+1, j-1, wBytesPerLine);
  281. rgb[6][0] = *(lpDIBBits+lOffset++);
  282. rgb[6][1] = *(lpDIBBits+lOffset++);
  283. rgb[6][2] = *(lpDIBBits+lOffset++);
  284. lOffset = this->PixelOffset( i+1, j, wBytesPerLine);
  285. rgb[7][0] = *(lpDIBBits+lOffset++);
  286. rgb[7][1] = *(lpDIBBits+lOffset++);
  287. rgb[7][2] = *(lpDIBBits+lOffset++);
  288. lOffset = this->PixelOffset( i+1, j+1, wBytesPerLine);
  289. rgb[8][0] = *(lpDIBBits+lOffset++);
  290. rgb[8][1] = *(lpDIBBits+lOffset++);
  291. rgb[8][2] = *(lpDIBBits+lOffset++);
  292.  this->MedianSearch( rgb,9,b,g,r);
  293. }
  294. int DIB::MedianSearch(int a[9][3],int n,int *r,int *g,int *b)
  295. {
  296. int result,i,j,temp;
  297. //冒泡法排序,找出rgb中间值
  298. for(i=0;i<9;i++)
  299. for(j = 0 ;j<n-i-1;j++)
  300. {
  301. if(a[j][0]>a[j+1][0])
  302. {
  303. temp = a[j][0];
  304. a[j][0] = a[j+1][0];
  305. a[j+1][0]=temp;
  306. }
  307. if(a[j][1]>a[j+1][1])
  308. {
  309. temp = a[j][1];
  310. a[j][1] = a[j+1][1];
  311. a[j+1][1]=temp;
  312. }
  313. if(a[j][2]>a[j+1][2])
  314. {
  315. temp = a[j][2];
  316. a[j][2] = a[j+1][2];
  317. a[j+1][2]=temp;
  318. }
  319. }
  320. //得到rgb得中间值
  321. *b = a[5][0];
  322. *g = a[5][1];
  323. *r = a[5][2];
  324. //根据需要也可以选用灰度值
  325. result = (a[5][0]*39 +a[5][1]*50 + a[5][2]*11)/100;
  326. return result;
  327. }
  328. //实现图片的黑白二值化
  329. void DIB::WhiteBlack(HANDLE hDIB,unsigned n)
  330. {
  331. LPBITMAPINFOHEADER  lpbi;
  332. LPBYTE lpS;
  333. int width,height;
  334. long lOffset;
  335. WORD                wBytesPerLine;
  336. if(!hDIB)
  337. return ;
  338. wBytesPerLine = this->BytePerLine(hDIB);
  339. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  340.     //得到图片的长宽信息
  341. width = lpbi->biWidth;
  342. height = lpbi->biHeight;
  343. lpS = (LPBYTE)lpbi;
  344. //lps指向数据区
  345. lpS = lpS + sizeof(BITMAPINFOHEADER);
  346.    //扫描整个图片,实现二值化
  347. for(int i = 0;i<height;i++)
  348. for(int j = 0 ;j<width;j++)
  349. {   //得到象素数据在数据区中的偏移
  350. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  351. if(*(lpS+lOffset)<n)//象素值小于临界值
  352. {   //把象素填充为黑色
  353. *(lpS+lOffset++) = 0;
  354. *(lpS+lOffset++) = 0;
  355. *(lpS+lOffset)   = 0;
  356. }
  357. else //象素值大于临界值
  358. {   
  359. //把象素填充为白色
  360. *(lpS+lOffset++) = 255;
  361. *(lpS+lOffset++) = 255;
  362. *(lpS+lOffset)   = 255;
  363. }
  364. }
  365. GlobalUnlock(hDIB);
  366. }
  367. DIB::DIB()
  368. {
  369. }
  370. DIB::~DIB()
  371. {
  372. }
  373. CPoint DIB::NextBorderPoint(CPoint CurrentPoint,LPBYTE lpDIBBits,WORD wBytesPerLine)
  374. {
  375. CPoint Pointtmp;
  376. /* Pointtmp.x=-1;
  377. Pointtmp.y=-1;
  378. if(CurrentPoint.x!=this->width-1)
  379. {
  380. Pointtmp.x=CurrentPoint.x+1;
  381. Pointtmp.y=CurrentPoint.y;
  382. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  383. return Pointtmp;
  384. }
  385. if((CurrentPoint.y!=this->height-1)&&(CurrentPoint.x!=this->width-1))
  386. {
  387. Pointtmp.x=CurrentPoint.x+1;
  388. Pointtmp.y=CurrentPoint.y+1;
  389. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  390. return Pointtmp;
  391. }
  392. if(CurrentPoint.y!=this->height-1)
  393. {
  394. Pointtmp.x=CurrentPoint.x;
  395. Pointtmp.y=CurrentPoint.y+1;
  396. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  397. return Pointtmp;
  398. }
  399. if((CurrentPoint.x!=0)&&(CurrentPoint.y!=this->height-1))
  400. {
  401. Pointtmp.x=CurrentPoint.x-1;
  402. Pointtmp.y=CurrentPoint.y+1;
  403. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  404. return Pointtmp;
  405. }
  406. if(CurrentPoint.x!=0)
  407. {
  408. Pointtmp.x=CurrentPoint.x-1;
  409. Pointtmp.y=CurrentPoint.y;
  410. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  411. return Pointtmp;
  412. }
  413. if((CurrentPoint.x!=0)&&(CurrentPoint.y!=0))
  414. {
  415. Pointtmp.x=CurrentPoint.x-1;
  416. Pointtmp.y=CurrentPoint.y-1;
  417. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  418. return Pointtmp;
  419. }
  420. if(CurrentPoint.y != 0)
  421. {
  422. Pointtmp.x = CurrentPoint.x;
  423. Pointtmp.y = CurrentPoint.y-1;
  424. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  425. return Pointtmp;
  426. }
  427.     if((CurrentPoint.y!=0)&&(CurrentPoint.x!=this->width-1))
  428. {
  429. Pointtmp.y=CurrentPoint.y-1;
  430. Pointtmp.x=CurrentPoint.x+1;
  431. if(this->IsBorderPoint(Pointtmp,lpDIBBits, wBytesPerLine))
  432. return Pointtmp;
  433. }
  434. CPoint errorPoint;
  435. errorPoint.x=errorPoint.y=-2;
  436. return errorPoint;
  437. */
  438. return Pointtmp;
  439. }
  440. BOOL DIB::IsBorderPoint(CPoint CurrentPoint ,LPBYTE lpDIBBits,WORD wBytesPerLine)
  441. {
  442. long lOffset;
  443. lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x,wBytesPerLine);
  444. if(*(lpDIBBits+lOffset)!=0)
  445. return false;
  446. if(CurrentPoint.y!=0)
  447. {
  448. lOffset = this->PixelOffset(CurrentPoint.y-1,CurrentPoint.x,wBytesPerLine);
  449. if(*(lpDIBBits+lOffset)==255)
  450. return true;
  451. }
  452. if(CurrentPoint.x!=this->width-1)
  453. {
  454. lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x+1,wBytesPerLine);
  455. if(*(lpDIBBits+lOffset)==255)
  456. return true;
  457. }
  458. if(CurrentPoint.y!=this->height-1)
  459. {
  460. lOffset = this->PixelOffset(CurrentPoint.y+1,CurrentPoint.x,wBytesPerLine);
  461. if(*(lpDIBBits+lOffset)==255)
  462. return true;
  463. }
  464. if(CurrentPoint.x!=0)
  465. {
  466. lOffset = this->PixelOffset(CurrentPoint.y,CurrentPoint.x-1,wBytesPerLine);
  467. if(*(lpDIBBits+lOffset)==255)
  468. return true;
  469. }
  470. return false;
  471. }
  472. CPoint DIB::SearchInteriorPoint(CPoint Point,LPBYTE lpDIBBits,WORD wBytesPerLine)
  473. {
  474. long lOffset;
  475. CPoint Pointtmp;
  476. Pointtmp.x=Pointtmp.y=-1;
  477. if((Point.x!=0)&&(Point.y!=this->height-1))
  478. {
  479. lOffset = this->PixelOffset(Point.y+1,Point.x-1,wBytesPerLine);
  480. if(*(lpDIBBits+lOffset)==0)
  481. {
  482. Pointtmp.x=Point.x-1;
  483. Pointtmp.y=Point.y+1;
  484. return Pointtmp;
  485. }
  486. }
  487. if(Point.y!=this->height-1)
  488. {
  489. lOffset = this->PixelOffset(Point.y+1,Point.x,wBytesPerLine);
  490. if(*(lpDIBBits+lOffset)==0)
  491. {
  492. Pointtmp.x=Point.x;
  493. Pointtmp.y=Point.y+1;
  494. return Pointtmp;
  495. }
  496. }
  497. if((Point.x!=this->width-1)&&(Point.y!=this->height-1))
  498. {
  499. lOffset = this->PixelOffset(Point.y+1,Point.x+1,wBytesPerLine);
  500. if(*(lpDIBBits+lOffset)==0)
  501. {
  502. Pointtmp.x=Point.x+1;
  503. Pointtmp.y=Point.y+1;
  504. return Pointtmp;
  505. }
  506. }
  507. if(Point.x!=this->width-1)
  508. {
  509. lOffset=this->PixelOffset(Point.y,Point.x+1,wBytesPerLine);
  510. if(*(lpDIBBits+lOffset)==0)
  511. {
  512. Pointtmp.x=Point.x+1;
  513. Pointtmp.y=Point.y;
  514. return Pointtmp;
  515. }
  516. }
  517. return Pointtmp;
  518. }
  519. BOOL DIB:: SaveDIB(HANDLE hDib, CFile& file)
  520. {
  521. // Bitmap文件头
  522. BITMAPFILEHEADER bmfHdr;
  523. // 指向BITMAPINFOHEADER的指针
  524. LPBITMAPINFOHEADER lpBI;
  525. // DIB大小
  526. DWORD dwDIBSize =0;
  527. if (hDib == NULL)
  528. {
  529. // 如果DIB为空,返回FALSE
  530. return FALSE;
  531. }
  532. // 读取BITMAPINFO结构,并锁定
  533. lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib);
  534. if (lpBI == NULL)
  535. {
  536. // 为空,返回FALSE
  537. return FALSE;
  538. }
  539. // 判断是否是WIN3.0 DIB
  540. // if (!IS_WIN30_DIB(lpBI))
  541. // {
  542. // 不支持其它类型的DIB保存
  543. // 解除锁定
  544. // ::GlobalUnlock((HGLOBAL) hDib);
  545. // 返回FALSE
  546. // return FALSE;
  547. // }
  548. // 填充文件头
  549. // 文件类型"BM"
  550. bmfHdr.bfType =  0x4d42; //DIB_HEADER_MARKER;
  551. // 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并
  552. // 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。
  553. // 文件头大小+颜色表大小
  554. // (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)
  555. // dwDIBSize = *(LPDWORD)lpBI; //+ ::PaletteSize((LPSTR)lpBI);
  556. dwDIBSize = sizeof(BITMAPINFOHEADER);//+lpBI->biSizeImage;
  557. // 计算图像大小
  558. if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
  559. {
  560. // 对于RLE位图,没法计算大小,只能信任biSizeImage内的值
  561. dwDIBSize += lpBI->biSizeImage;
  562. }
  563. else
  564. {
  565. // 象素的大小
  566. DWORD dwBmBitsSize;
  567. // 大小为Width * Height
  568. dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*24) * lpBI->biHeight;
  569. // 计算出DIB真正的大小
  570. dwDIBSize += dwBmBitsSize;
  571. // 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)
  572. lpBI->biSizeImage = dwBmBitsSize;
  573. }
  574. // 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小
  575. bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
  576. // 两个保留字
  577. bmfHdr.bfReserved1 = 0;
  578. bmfHdr.bfReserved2 = 0;
  579. // 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小
  580. bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize;
  581.  // + PaletteSize((LPSTR)lpBI);
  582. // 尝试写文件
  583. // TRY
  584. {
  585. // 写文件头
  586. file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
  587. // 写DIB头和象素
  588. file.WriteHuge(lpBI, dwDIBSize);
  589. }
  590. // CATCH (CFileException, e)
  591. // {
  592. // 解除锁定
  593. // ::GlobalUnlock((HGLOBAL) hDib);
  594. // 抛出异常
  595. /// THROW_LAST();
  596. // }
  597. // END_CATCH
  598. // 解除锁定
  599. ::GlobalUnlock((HGLOBAL) hDib);
  600. // 返回TRUE
  601. return TRUE;
  602. }
  603. HANDLE DIB::ScaleDIB(HANDLE hDIB, float scal_x, float scal_y)
  604. {
  605. if(scal_x<0 || scal_y <0)
  606. return NULL;
  607. LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
  608. int w = lpbi->biWidth;
  609. int h = lpbi->biHeight;
  610. BYTE  tempmess[40];
  611. LPBYTE Src = this->FindDIBBits(hDIB);
  612. memcpy(tempmess,(LPBYTE)lpbi,40);
  613. int wid = ((int)(w*scal_x+0.5f)*24+31)/32*4;
  614. int imgsize =(int) (wid*(int)(h*scal_y+0.5f));
  615. HDIB hDIB2 = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(sizeof(BITMAPINFOHEADER)+imgsize));
  616. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
  617. memcpy((LPBYTE)lpbi,tempmess,40);
  618. lpbi->biWidth =(int)(w*scal_x+0.5f);
  619. lpbi->biHeight = (int)(h*scal_y+0.5f);
  620. lpbi->biSizeImage = imgsize;
  621. LPBYTE lpData = this->FindDIBBits(hDIB2);
  622. int srcWidth = w;
  623. int srcHeight = h;
  624. int dstWidth = (int)(w*scal_x+0.5f);
  625. int dstHeight = (int)(h*scal_y+0.5f);
  626. for(int i=0; i<dstHeight;i++)
  627. {
  628. float y_inverse_map = (float)i/scal_y;
  629. int y_lt = (int)y_inverse_map;
  630. float v=y_inverse_map - y_lt;
  631. int indexBase = i *wid;
  632. for(int j=0;j<dstWidth;j++)
  633. {
  634. float x_inverse_map = (float)j/scal_x;
  635. int x_lt = (int) x_inverse_map;
  636. float u=x_inverse_map - x_lt;
  637. int index = indexBase + j*3;
  638. *(lpData+index) = Src[y_lt*((w*24+31)/32*4)+x_lt*3];
  639. *(lpData+index+1) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+1];
  640. *(lpData+index+2) = Src[y_lt*((w*24+31)/32*4)+x_lt*3+2];
  641. // int r,g,b;
  642. //((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b))) ;
  643. // *(lpData+temp)   = b;
  644. //*(lpData+index++)   = (BYTE)((interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight)>>16)) & 0x000000ff;
  645. // (interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
  646. // *(lpData+temp+1)   = g;
  647.   //  (interPolate(Src,x_lt,y_lt,u,v,srcWidth,srcHeight,&r,&g,&b));
  648. //  *(lpData+temp+2)   =r;
  649. }
  650. }
  651. GlobalUnlock(hDIB);
  652. GlobalUnlock(hDIB2);
  653. return hDIB2;
  654. }
  655. //cwh 01.6.20
  656. /*****************************************
  657. 卷积核心算法
  658. *****************************************/
  659. void DIB::interPolate(LPBYTE Src,int x,int y, float u,float v, int scanw, int scanh,int *r,int *g,int *b)
  660. {
  661. // UINT r11,g11,b11;
  662. //r=g=b=0;
  663. int red1[2][2];
  664. int green1[2][2];
  665. int blue1[2][2];
  666. int xx1[2];
  667. int yy1[2];
  668. xx1[0]=x*3;xx1[1]=x*3+3;
  669. yy1[0]=y;yy1[1]=y+1;
  670. if(xx1[1]>scanw-1)
  671. xx1[1] = scanw-1;
  672. if(yy1[1]>scanh-1)
  673. yy1[1] = scanh-1;
  674. for(int i=0;i<2;i++)
  675. {
  676. int indexBase1 = yy1[i]*((scanw*24+31)/32*4);
  677. for(int j=0;j<2;j++)
  678. {
  679. int index1 = indexBase1 + xx1[j];
  680. blue1[j][i] = (*(Src+index1));
  681.     green1[j][i] = (*(Src+index1+1));
  682.     red1[j][i] =  (*(Src+index1+2));
  683. }
  684. }
  685. //r11 = ((1-u)*(1-v)*red1[0][0]+(1-u)*v*red1[0][1]+u*(1-v)*red1[1][0]+u*v*red1[1][1]);
  686. // g11 = ((1-u)*(1-v)*green1[0][0]+(1-u)*v*green1[0][1]+u*(1-v)*green1[1][0]+u*v*green1[1][1]);
  687. //b11 = ((1-u)*(1-v)*blue1[0][0]+(1-u)*v*blue1[0][1]+u*(1-v)*blue1[1][0]+u*v*blue1[1][1]);
  688.   
  689. // *r=r11;
  690. //*g=g11;
  691. // *b=b11;
  692. // return (0x00ffffff&((b<<16)|(g<<8)|r));
  693. }
  694. HANDLE DIB::CopyHandle( HANDLE hSrc)
  695. {
  696. HANDLE hDst;
  697. LPBITMAPINFOHEADER lpbi;
  698. int width,height;
  699. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hSrc);
  700. width = lpbi->biWidth;
  701. height = lpbi->biHeight;
  702. hDst = GlobalAlloc(GMEM_MOVEABLE,lpbi->biSize+lpbi->biSizeImage);
  703. if(!hDst)
  704. return NULL;
  705. LPBYTE lpDest;
  706. lpDest = (LPBYTE)GlobalLock(hDst);
  707. memcpy(lpDest,(LPBYTE)lpbi,lpbi->biSize+lpbi->biSizeImage);
  708. GlobalUnlock(hSrc);
  709. GlobalUnlock(hDst);
  710. return hDst;
  711. }
  712. HANDLE  DIB::  Gradient(HANDLE hDIB)
  713. {
  714. LPBITMAPINFOHEADER lpbi;
  715. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  716. int width = lpbi->biWidth;
  717. int height = lpbi->biHeight;
  718. long lOffset;
  719. LPBYTE lpS,lpD;
  720. WORD wBytesPerLine = this->BytePerLine(hDIB);
  721. HANDLE hNewDIB;
  722. hNewDIB = GlobalAlloc(GMEM_MOVEABLE,(DWORD)(lpbi->biSize+lpbi->biSizeImage));
  723. if(!hNewDIB)
  724. {
  725. AfxMessageBox("分配内存失败");
  726. return NULL;
  727. }
  728. lpS = (LPBYTE)lpbi;
  729. lpD =(LPBYTE) GlobalLock(hNewDIB);
  730. memcpy(lpD,lpS,sizeof(BITMAPINFOHEADER));
  731. lpS = this->FindDIBBits(hDIB);
  732. lpD = this->FindDIBBits(hNewDIB);
  733. int color1,color2;
  734. for(int i=1;i<height-1;i++)
  735. for(int j=1;j<width-1;j++)
  736. {
  737. lOffset = this->PixelOffset(i+1,j+1,wBytesPerLine);
  738. color1 = *(lpS+lOffset);
  739. lOffset = this->PixelOffset(i-1,j-1,wBytesPerLine);
  740. color2 = *(lpS+lOffset);
  741. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  742. *(lpD+lOffset++) = abs(color2-color1)*3;
  743. *(lpD+lOffset++) = abs(color2-color1)*3;
  744. *(lpD+lOffset++) = abs(color2-color1)*3;
  745. }
  746. for(i =0;i<height;i++)
  747. {
  748. lOffset = this->PixelOffset(i,0,wBytesPerLine);
  749. *(lpD+lOffset++) =0;
  750. *(lpD+lOffset++) =0;
  751. *(lpD+lOffset++) =0;
  752. }
  753. for(i =0;i<height;i++)
  754. {
  755. lOffset = this->PixelOffset(i,width-1,wBytesPerLine);
  756. *(lpD+lOffset++) =0;
  757. *(lpD+lOffset++) =0;
  758. *(lpD+lOffset++) =0;
  759. }
  760. for(i =0;i<width;i++)
  761. {
  762. lOffset = this->PixelOffset(height-1,i,wBytesPerLine);
  763. *(lpD+lOffset++) =0;
  764. *(lpD+lOffset++) =0;
  765. *(lpD+lOffset++) =0;
  766. }
  767. for(i =0;i<width;i++)
  768. {
  769. lOffset = this->PixelOffset(0,i,wBytesPerLine);
  770. *(lpD+lOffset++) =0;
  771. *(lpD+lOffset++) =0;
  772. *(lpD+lOffset++) =0;
  773. }
  774. GlobalUnlock(hNewDIB);
  775. GlobalUnlock(hDIB);
  776. return hNewDIB;
  777. }
  778. //函数寻找图片中的特征区域的中心点
  779. void DIB::LocateImporntPoint(HANDLE hDIB, int Radius, CPoint *pPoint)
  780. {
  781. LPBITMAPINFOHEADER lpbi;
  782. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  783. int width ,height;
  784. width = lpbi->biWidth;
  785. height = lpbi->biHeight;
  786. WORD wBytesPerLine;
  787. wBytesPerLine = this->BytePerLine(hDIB);
  788. LPBYTE lpData;
  789. lpData = this->FindDIBBits(hDIB);
  790. int tempsum=0,sum=0;//定义两个变量用来记数
  791. long lOffset;
  792. //扫描整个图片(边缘点除外)寻找特征区域
  793. for(int i=Radius;i<height-Radius;i++)
  794. for(int j= Radius;j<width-Radius;j++)
  795. { tempsum =0;
  796. //扫描以Radius×2+1为边长的正方形区域
  797. for(int k1=-Radius;k1<=Radius;k1++)
  798. for(int k2 =-Radius;k2<=Radius;k2++)
  799. {
  800. lOffset = this->PixelOffset(i+k1,j+k2,wBytesPerLine);
  801. int color = *(lpData+lOffset);
  802. tempsum +=color;//累加象素值
  803. }
  804. if(tempsum>sum)//如果得到的累计象素值大于已经得到的最大值
  805. {
  806. //更改累计象素值大小
  807. sum = tempsum;
  808. //更改特征区域中心点
  809. (pPoint->x) = j;
  810. (pPoint->y) = i;
  811.    
  812. }
  813. }
  814. //下面的代码把特征区域的边框设置成白色
  815. for( i = -Radius;i<=Radius;i++)
  816. {
  817. lOffset = this->PixelOffset(pPoint->y-Radius,pPoint->x +i,wBytesPerLine);
  818. *(lpData+lOffset++) = 255;
  819. *(lpData+lOffset++) = 255;
  820. *(lpData+lOffset++) = 255;
  821. }
  822. for( i = -Radius;i<=Radius;i++)
  823. {
  824. lOffset = this->PixelOffset(pPoint->y+Radius,pPoint->x +i,wBytesPerLine);
  825. *(lpData+lOffset++) = 255;
  826. *(lpData+lOffset++) = 255;
  827. *(lpData+lOffset++) = 255;
  828. }
  829. for( i = -Radius;i<=Radius;i++)
  830. {
  831. lOffset = this->PixelOffset(pPoint->y+i,pPoint->x-Radius ,wBytesPerLine);
  832. *(lpData+lOffset++) = 255;
  833. *(lpData+lOffset++) = 255;
  834. *(lpData+lOffset++) = 255;
  835. }
  836. for( i = -Radius;i<=Radius;i++)
  837. {
  838. lOffset = this->PixelOffset(pPoint->y+i,pPoint->x+Radius,wBytesPerLine);
  839. *(lpData+lOffset++) = 255;
  840. *(lpData+lOffset++) = 255;
  841. *(lpData+lOffset++) = 255;
  842. }
  843. lOffset = this->PixelOffset(pPoint->y,pPoint->x ,wBytesPerLine);
  844. *(lpData+lOffset++) = 0;
  845. *(lpData+lOffset++) = 255;
  846. *(lpData+lOffset++) = 0;
  847. GlobalUnlock(hDIB);
  848. }
  849. #define THRESHOLD (RADIUS*2+1)*(RADIUS*2+1)*15
  850. //函数在一幅图片中寻找匹配的中心点
  851. BOOL DIB::MatchImportantPoint(HANDLE hDIB,int CharaterInfo[RADIUS*2+1][RADIUS*2+1][3],CPoint *ImPoint)
  852. {
  853. LPBITMAPINFOHEADER lpbi;
  854. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  855. int width = lpbi->biWidth;
  856. int height = lpbi->biHeight;
  857. LPBYTE lpData = this->FindDIBBits(hDIB);
  858.     WORD wBytesPerLine = this->BytePerLine(hDIB);
  859. long lOffset;
  860. long sum =100000,tempsum;
  861. //扫描整个图片(边缘点)除外
  862. for(int i=RADIUS ;i<height-RADIUS;i++)
  863. for(int j=RADIUS;j<width-RADIUS;j++)
  864. {
  865. tempsum =0;
  866. //扫描以RADIUS*2+1为边长的正方形区域
  867. for(int k=-RADIUS;k<=RADIUS;k++)
  868. for(int kk=-RADIUS;kk<=RADIUS;kk++)
  869. {
  870. //计算当前正方形和已知特征区域的颜色差值
  871. lOffset = this->PixelOffset(i+k,j+kk,wBytesPerLine);
  872. int colorblue = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][0]);
  873. int colorgreen = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][1]);
  874. int colorred = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][2]);
  875. tempsum +=colorgreen+colorblue+colorred;
  876. }
  877. if(tempsum<sum)
  878. {  //更新差值
  879. sum = tempsum;
  880. //更改特征坐标点
  881. ImPoint->x = j;
  882. ImPoint->y = i;
  883. }
  884. }
  885. if(sum <THRESHOLD){//找到满足条件的区域
  886. //下面的代码把找到的区域的边框设置成为白色
  887. for(i =-RADIUS;i<=RADIUS;i++)
  888. {
  889. lOffset = this->PixelOffset(ImPoint->y-RADIUS,ImPoint->x+i,wBytesPerLine);
  890. *(lpData+lOffset++) = 255;
  891. *(lpData+lOffset++) = 255;
  892. *(lpData+lOffset++) = 255;
  893. }
  894. for(i =-RADIUS;i<=RADIUS;i++)
  895. {
  896. lOffset = this->PixelOffset(ImPoint->y+RADIUS,ImPoint->x+i,wBytesPerLine);
  897. *(lpData+lOffset++) = 255;
  898. *(lpData+lOffset++) = 255;
  899. *(lpData+lOffset++) = 255;
  900. }
  901. for(i =-RADIUS;i<=RADIUS;i++)
  902. {
  903. lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x+RADIUS,wBytesPerLine);
  904. *(lpData+lOffset++) = 255;
  905. *(lpData+lOffset++) = 255;
  906. *(lpData+lOffset++) = 255;
  907. }
  908. for(i =-RADIUS;i<=RADIUS;i++)
  909. {
  910. lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x-RADIUS,wBytesPerLine);
  911. *(lpData+lOffset++) = 255;
  912. *(lpData+lOffset++) = 255;
  913. *(lpData+lOffset++) = 255;
  914. }
  915. GlobalUnlock(hDIB);
  916. return true;
  917. }
  918. else AfxMessageBox("Can't find the corresponding point!");
  919. GlobalUnlock(hDIB);
  920. return false;
  921. }
  922. //比较两张图片的相似度
  923. BOOL DIB::ComPareImg(HANDLE hDIB1, HANDLE hDIB2 ,CPoint pt1,CPoint pt2)
  924. {
  925. if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)//图象偏差过大
  926. {
  927. AfxMessageBox("Imgs Offset are too big");
  928. return false;
  929. }
  930. LPBITMAPINFOHEADER lpbi1,lpbi2;
  931. lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIB1);
  932. int width1 = lpbi1->biWidth;
  933. int height1 = lpbi1->biHeight;
  934. lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
  935. int width2 = lpbi2->biWidth;
  936. int height2 = lpbi2->biHeight;
  937. if(width1 != width2 || height1 != height2)//图象长宽尺寸不同
  938. {
  939. GlobalUnlock(hDIB1);
  940. GlobalUnlock(hDIB2);
  941. AfxMessageBox("Img is not same size");
  942. return false;
  943. }
  944. LPBYTE lpData1,lpData2;
  945. lpData1 = this->FindDIBBits(hDIB1);
  946. lpData2 = this->FindDIBBits(hDIB2);
  947. WORD wBytesPerLine = this->BytePerLine(hDIB1);
  948. int xleft,xright,ytop,ybottom;
  949. //下面的一段代码实现图象对齐
  950. if(pt1.x>=pt2.x)//第一幅图得特征中心点比第二幅图偏右
  951. {
  952. xleft = pt2.x;//要处理得左边得象素点个数
  953. xright =width-pt1.x-1;//要处理得右边得象素点个数
  954. }
  955. else//第一幅图得特征中心点比第二幅图偏左
  956. {
  957. xleft = pt1.x;
  958. xright = width1-pt2.x-1;
  959. }
  960. if(pt1.y >=pt2.y)//第一幅图得特征中心点得位置偏上
  961. {
  962. ytop = pt2.y;//要处理得中心点上面得象素个数
  963. ybottom = height1-pt1.y-1;//要处理得中心点下面得象素个数
  964. }
  965. else//第一幅图得特征中心点得位置偏下
  966. {
  967. ytop = pt1.y;
  968. ybottom = height1-pt2.y-1;
  969. }
  970. long sum=0;
  971. long lOffset;
  972. //计算两幅图片交叉区域得象素差值
  973. for(int i=-ytop;i<=ybottom;i++)
  974. for(int j=-xleft;j<=xright;j++)
  975. {
  976. //第一幅图
  977. lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
  978. int c11 = *(lpData1+lOffset++);
  979. int c12 = *(lpData1+lOffset++);
  980. int c13 = *(lpData1+lOffset++);
  981. //第二幅图
  982. lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
  983. int c21 = *(lpData2+lOffset++);
  984. int c22 = *(lpData2+lOffset++);
  985. int c23 = *(lpData2+lOffset++);
  986. //计算差值
  987. sum += abs(c11-c21)+abs(c12-c22)+abs(c13-c23);
  988. }
  989. GlobalUnlock(hDIB1);
  990. GlobalUnlock(hDIB2);
  991. if(sum>width1*height1*3*2)//判断是否相似
  992. return false;
  993. else 
  994. return true;
  995. }
  996. BOOL DIB::  CompareImg2(HANDLE hDIBBK,HANDLE hDIBCurrent,CPoint pt1,CPoint pt2)
  997. {
  998. if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)
  999. {
  1000. AfxMessageBox("Imgs Offset are too big");
  1001. return false;
  1002. }
  1003. LPBITMAPINFOHEADER lpbi1,lpbi2;
  1004. lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIBBK);
  1005. int width1 = lpbi1->biWidth;
  1006. int height1 = lpbi1->biHeight;
  1007. lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIBCurrent);
  1008. int width2 = lpbi2->biWidth;
  1009. int height2 = lpbi2->biHeight;
  1010. if(width1 != width2 || height1 != height2)
  1011. {
  1012. GlobalUnlock(hDIBBK);
  1013. GlobalUnlock(hDIBCurrent);
  1014. AfxMessageBox("Img is not same size");
  1015. return false;
  1016. }
  1017. LPBYTE lpData1,lpData2;
  1018. lpData1 = this->FindDIBBits(hDIBBK);
  1019. lpData2 = this->FindDIBBits(hDIBCurrent);
  1020. WORD wBytesPerLine = this->BytePerLine(hDIBBK);
  1021. int xleft,xright,ytop,ybottom;
  1022. if(pt1.x>=pt2.x)
  1023. {
  1024. xleft = pt2.x;
  1025. xright =width1-pt1.x-1;
  1026. }
  1027. else
  1028. {
  1029. xleft = pt1.x;
  1030. xright = width1-pt2.x-1;
  1031. }
  1032. if(pt1.y >=pt2.y)
  1033. {
  1034. ytop = pt2.y;
  1035. ybottom = height1-pt1.y-1;
  1036. }
  1037. else
  1038. {
  1039. ytop = pt1.y;
  1040. ybottom = height1-pt2.y-1;
  1041. }
  1042. long sum=0;
  1043. long lOffset;
  1044. for(int i=-ytop;i<=ybottom;i++)
  1045. for(int j=-xleft;j<=xright;j++)
  1046. {
  1047. lOffset = this->PixelOffset(i+pt1.y,j+pt1.x,wBytesPerLine);
  1048. int c11 = *(lpData1+lOffset++);
  1049. int c12 = *(lpData1+lOffset++);
  1050. int c13 = *(lpData1+lOffset++);
  1051. lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
  1052. int c21 = *(lpData2+lOffset++);
  1053. int c22 = *(lpData2+lOffset++);
  1054. int c23 = *(lpData2+lOffset++);
  1055. lOffset = this->PixelOffset(i+pt2.y,j+pt2.x,wBytesPerLine);
  1056. *(lpData2+lOffset++) = abs(c11-c21);
  1057. *(lpData2+lOffset++) = abs(c12-c22);
  1058. *(lpData2+lOffset++) = abs(c13-c23);
  1059. }
  1060. for(i =0;i<height1;i++)
  1061. for(int j=0;j<width1;j++)
  1062. {
  1063. if(i<pt2.y-ytop || i>pt2.y+ybottom||j<pt2.x-xleft || j >pt2.x+xright)
  1064. {
  1065. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  1066. *(lpData2+lOffset++) = 0;
  1067. *(lpData2+lOffset++) = 0;
  1068. *(lpData2+lOffset++) = 0;
  1069. }
  1070. }
  1071. GlobalUnlock(hDIBBK);
  1072. GlobalUnlock(hDIBCurrent);
  1073. return true;
  1074. }
  1075. BOOL DIB::IsScaterPoint(int x, int y, int width, int height, LPBYTE lpData,WORD wBytesPerLine,  int threshold,bool lab[m_HEIGHT][m_WIDTH])
  1076. {
  1077. long lOffset;
  1078. lOffset = this->PixelOffset(y,x,wBytesPerLine);
  1079. if(*(lpData+lOffset) == 255 && lab[y][x] == false)
  1080. {
  1081. this->lenth++;
  1082. lab[y][x] = true;
  1083. if(this->lenth >= threshold)
  1084. return true;
  1085. if(x+1<width && lab[y][x+1] == false)
  1086. { IsScaterPoint(x+1,y,width,height,lpData,wBytesPerLine,threshold,lab);
  1087. if(this->lenth>=threshold)
  1088. return true;
  1089. }
  1090. if(x-1>=0 && lab[y][x-1] == false)
  1091. {
  1092. (IsScaterPoint(x-1,y,width,height,lpData,wBytesPerLine,threshold,lab));
  1093. if(this->lenth>=threshold)
  1094. return true;
  1095. }
  1096. if(y-1>=0 && lab[y-1][x]==false)
  1097. {
  1098. (IsScaterPoint(x,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
  1099. if(this->lenth>=threshold)
  1100. return true;
  1101. }
  1102. if(y+1<height && lab[y+1][x]==false)
  1103. { (IsScaterPoint(x,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
  1104. if(this->lenth>=threshold)
  1105. return true;
  1106. }
  1107. if(y+1<height  && x+1 <width && lab[y+1][x+1]==false)
  1108. { (IsScaterPoint(x+1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
  1109. if(this->lenth>=threshold)
  1110. return true;
  1111. }
  1112. if(y+1<height && x-1 >=0 && lab[y+1][x-1]==false)
  1113. { (IsScaterPoint(x-1,y+1,width,height,lpData,wBytesPerLine,threshold,lab));
  1114. if(this->lenth>=threshold)
  1115. return true;
  1116. }
  1117. if(y-1>=0 && x-1 >=0 &&lab[y-1][x-1]==false)
  1118. { (IsScaterPoint(x-1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
  1119. if(this->lenth>=threshold)
  1120. return true;
  1121. }
  1122. if(y-1<height && x+1<width && lab[y+1][x]==false)
  1123. { (IsScaterPoint(x+1,y-1,width,height,lpData,wBytesPerLine,threshold,lab));
  1124. if(this->lenth>=threshold)
  1125. return true;
  1126. }
  1127. }
  1128. return false;
  1129. }
  1130. //函数得到边界得中心点
  1131. CPoint DIB:: GetEdgeCenter(HANDLE hDIB)
  1132. {
  1133. LPBITMAPINFOHEADER lpbi;
  1134. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
  1135. int width = lpbi->biWidth;
  1136. int height = lpbi->biHeight;
  1137. WORD wBytesPerLine = this->BytePerLine(hDIB);
  1138. LPBYTE lpData = this->FindDIBBits(hDIB);
  1139. long lOffset;
  1140. int x =0,y =0,num =0;
  1141. //对整幅图片进行扫描
  1142. for(int i=0;i<height;i++)
  1143. for(int j=0;j<width;j++)
  1144. {
  1145. lOffset = this->PixelOffset(i,j,wBytesPerLine);
  1146. if(*(lpData+lOffset) ==255)//如果是白色象素
  1147. {
  1148. x +=j;//中心点得横坐标和纵坐标加上当前得横坐标和纵坐标
  1149. y +=i;
  1150. num++;
  1151. }
  1152. }
  1153. //得到结果坐标点
  1154. CPoint result;
  1155. result.x = x/num;
  1156. result.y = y/num;
  1157. //把中心点设置为绿色
  1158. lOffset = this->PixelOffset(result.y,result.x,wBytesPerLine);
  1159. *(lpData+lOffset++) = 0;
  1160. *(lpData+lOffset++) = 255;
  1161. *(lpData+lOffset++) = 0;
  1162. return result;
  1163. }