TypeRecView.cpp
上传用户:renhuadsj
上传日期:2008-11-19
资源大小:1466k
文件大小:23k
源码类别:

图形图象

开发平台:

Visual C++

  1. // TypeRecView.cpp : implementation of the CTypeRecView class
  2. //
  3. #include "stdafx.h"
  4. #include "TypeRec.h"
  5. #include "mainfrm.h"
  6. #include "io.h"
  7. #include "direct.h"
  8. #include "string.h"
  9. #include "TypeRecDoc.h"
  10. #include "TypeRecView.h"
  11. #include "ColorTable.h"
  12. //#include "suanfa1.h"
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CTypeRecView
  20. IMPLEMENT_DYNCREATE(CTypeRecView, CView)
  21. BEGIN_MESSAGE_MAP(CTypeRecView, CView)
  22. //{{AFX_MSG_MAP(CTypeRecView)
  23. ON_WM_ERASEBKGND()
  24. ON_COMMAND(ID_FILE_256ToGray, OnFILE256ToGray)
  25. ON_COMMAND(ID_FILE_24ToGray, OnFILE24ToGray)
  26. ON_COMMAND(ID_TEMP_SUBRECT, OnTempSubrect)
  27. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  28. ON_COMMAND(ID_TEMP_PALETTE, OnTempPalette)
  29. ON_COMMAND(ID_TEMP_GRAY, OnTempGray)
  30. ON_COMMAND(ID_TEMP_ERROR, OnTempError)
  31. ON_COMMAND(ID_TEST_1_1, OnTest11)
  32. ON_COMMAND(ID_TEST_1_2, OnTest12)
  33. ON_COMMAND(ID_TEST_1_3, OnTest13)
  34. ON_COMMAND(ID_TEST_1_4, OnTest14)
  35. ON_COMMAND(ID_TEST_1_5, OnTest15)
  36. ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  37. ON_COMMAND(ID_TEST_1_45, OnTest145)
  38. ON_COMMAND(ID_TEST_1_6, OnTest16)
  39. //}}AFX_MSG_MAP
  40. // Standard printing commands
  41. ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
  42. ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
  43. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CTypeRecView construction/destruction
  47. CTypeRecView::CTypeRecView()
  48. {
  49. m_ipzLeft=0;
  50. m_ipzRight=0;
  51. m_ipzBottom=0;
  52. m_ipzTop=0;
  53. }
  54. CTypeRecView::~CTypeRecView()
  55. {
  56. }
  57. BOOL CTypeRecView::PreCreateWindow(CREATESTRUCT& cs)
  58. {
  59. // TODO: Modify the Window class or styles here by modifying
  60. //  the CREATESTRUCT cs
  61. return CView::PreCreateWindow(cs);
  62. }
  63. /////////////////////////////////////////////////////////////////////////////
  64. // CTypeRecView drawing
  65. void CTypeRecView::OnDraw(CDC* pDC)
  66. {
  67. // 显示等待光标
  68. BeginWaitCursor();
  69. // 获取文档
  70. CTypeRecDoc* pDoc = GetDocument();
  71. ASSERT_VALID(pDoc);
  72. // 获取DIB
  73. HDIB hDIB = pDoc->GetHDIB();
  74. // 判断DIB是否为空
  75. if (hDIB != NULL)
  76. {
  77. LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  78. // 获取DIB宽度
  79. int cxDIB = (int) ::DIBWidth(lpDIB);
  80. // 获取DIB高度
  81. int cyDIB = (int) ::DIBHeight(lpDIB);
  82. ::GlobalUnlock((HGLOBAL) hDIB);
  83. CRect rcDIB;
  84. rcDIB.top = rcDIB.left = 0;
  85. rcDIB.right = cxDIB;
  86. rcDIB.bottom = cyDIB;
  87. CRect rcDest;
  88. // 判断是否是打印
  89. if (pDC->IsPrinting())
  90. {
  91. // 是打印,计算输出图像的位置和大小,以便符合页面
  92. // 获取打印页面的水平宽度(象素)
  93. int cxPage = pDC->GetDeviceCaps(HORZRES);
  94. // 获取打印页面的垂直高度(象素)
  95. int cyPage = pDC->GetDeviceCaps(VERTRES);
  96. // 获取打印机每英寸象素数
  97. int cxInch = pDC->GetDeviceCaps(LOGPIXELSX);
  98. int cyInch = pDC->GetDeviceCaps(LOGPIXELSY);
  99. // 计算打印图像大小(缩放,根据页面宽度调整图像大小)
  100. rcDest.top = rcDest.left = 0;
  101. rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch)
  102. / ((double)cxDIB * cxInch));
  103. rcDest.right = cxPage;
  104. // 计算打印图像位置(垂直居中)
  105. int temp = cyPage - (rcDest.bottom - rcDest.top);
  106. rcDest.bottom += temp/2;
  107. rcDest.top += temp/2;
  108. }
  109. else   
  110. // 非打印
  111. {
  112. // 不必缩放图像
  113. rcDest = rcDIB;
  114. }
  115. // 输出DIB
  116. ::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(),
  117. &rcDIB, pDoc->GetDocPalette());
  118. }
  119. // 恢复正常光标
  120. EndWaitCursor();
  121. }
  122. /////////////////////////////////////////////////////////////////////////////
  123. // CTypeRecView printing
  124. BOOL CTypeRecView::OnPreparePrinting(CPrintInfo* pInfo)
  125. {
  126. // default preparation
  127. return DoPreparePrinting(pInfo);
  128. }
  129. void CTypeRecView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  130. {
  131. // TODO: add extra initialization before printing
  132. }
  133. void CTypeRecView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  134. {
  135. // TODO: add cleanup after printing
  136. }
  137. /////////////////////////////////////////////////////////////////////////////
  138. // CTypeRecView diagnostics
  139. #ifdef _DEBUG
  140. void CTypeRecView::AssertValid() const
  141. {
  142. CView::AssertValid();
  143. }
  144. void CTypeRecView::Dump(CDumpContext& dc) const
  145. {
  146. CView::Dump(dc);
  147. }
  148. CTypeRecDoc* CTypeRecView::GetDocument() // non-debug version is inline
  149. {
  150. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTypeRecDoc)));
  151. return (CTypeRecDoc*)m_pDocument;
  152. }
  153. #endif //_DEBUG
  154. /////////////////////////////////////////////////////////////////////////////
  155. // CTypeRecView message handlers
  156. BOOL CTypeRecView::OnEraseBkgnd(CDC* pDC) 
  157. {
  158. // 主要是为了设置子窗体默认的背景色
  159. // 背景色由文档成员变量m_refColorBKG指定
  160. // 获取文档
  161. CTypeRecDoc* pDoc = GetDocument();
  162. // 创建一个Brush
  163. CBrush brush(pDoc->m_refColorBKG);                                              
  164. // 保存以前的Brush
  165. CBrush* pOldBrush = pDC->SelectObject(&brush);
  166. // 获取重绘区域
  167. CRect rectClip;
  168. pDC->GetClipBox(&rectClip);
  169. // 重绘
  170. pDC->PatBlt(rectClip.left, rectClip.top, rectClip.Width(), rectClip.Height(), PATCOPY);
  171. // 恢复以前的Brush
  172. pDC->SelectObject(pOldBrush);                                                  
  173. // 返回
  174. return TRUE;
  175. }
  176. void CTypeRecView::OnFILE256ToGray() 
  177. {
  178. // 将256色位图转换成灰度图
  179. // 获取文档
  180. CTypeRecDoc* pDoc = GetDocument();
  181. // 指向DIB的指针
  182. LPSTR lpDIB;
  183. // 锁定DIB
  184. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
  185. // 颜色表中的颜色数目
  186. WORD wNumColors;
  187. // 获取DIB中颜色表中的颜色数目
  188. wNumColors = ::DIBNumColors(lpDIB);
  189. // 判断是否是8-bpp位图
  190. if (wNumColors != 256)
  191. {
  192. // 提示用户
  193. MessageBox("非256色位图!", "系统提示" , MB_ICONINFORMATION | MB_OK);
  194. // 解除锁定
  195. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  196. // 返回
  197. return;
  198. }
  199. // 更改光标形状
  200. BeginWaitCursor();
  201. // 指向DIB象素指针
  202. LPSTR   lpDIBBits;
  203. // 指向DIB象素的指针
  204. BYTE * lpSrc;
  205. // 循环变量
  206. LONG i;
  207. LONG j;
  208. // 图像宽度
  209. LONG lWidth;
  210. // 图像高度
  211. LONG lHeight;
  212. // 图像每行的字节数
  213. LONG lLineBytes;
  214. // 指向BITMAPINFO结构的指针(Win3.0)
  215. LPBITMAPINFO lpbmi;
  216. // 指向BITMAPCOREINFO结构的指针
  217. LPBITMAPCOREINFO lpbmc;
  218. // 表明是否是Win3.0 DIB的标记
  219. BOOL bWinStyleDIB;
  220. // 获取指向BITMAPINFO结构的指针(Win3.0)
  221. lpbmi = (LPBITMAPINFO)lpDIB;
  222. // 获取指向BITMAPCOREINFO结构的指针
  223. lpbmc = (LPBITMAPCOREINFO)lpDIB;
  224. // 灰度映射表
  225. BYTE bMap[256];
  226. // 判断是否是WIN3.0的DIB
  227. bWinStyleDIB = IS_WIN30_DIB(lpDIB);
  228. // 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
  229. for (i = 0; i < 256; i ++)
  230. {
  231. if (bWinStyleDIB)
  232. {
  233. // 计算该颜色对应的灰度值
  234. bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +
  235. 0.587 * lpbmi->bmiColors[i].rgbGreen +
  236. 0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);
  237. // 更新DIB调色板红色分量
  238. lpbmi->bmiColors[i].rgbRed =(unsigned char) i;
  239. // 更新DIB调色板绿色分量
  240. lpbmi->bmiColors[i].rgbGreen = (unsigned char)i;
  241. // 更新DIB调色板蓝色分量
  242. lpbmi->bmiColors[i].rgbBlue = (unsigned char)i;
  243. // 更新DIB调色板保留位
  244. lpbmi->bmiColors[i].rgbReserved = 0;
  245. }
  246. else
  247. {
  248. // 计算该颜色对应的灰度值
  249. bMap[i] = (BYTE)(0.299 * lpbmc->bmciColors[i].rgbtRed +
  250. 0.587 * lpbmc->bmciColors[i].rgbtGreen +
  251. 0.114 * lpbmc->bmciColors[i].rgbtBlue + 0.5);
  252. // 更新DIB调色板红色分量
  253. lpbmc->bmciColors[i].rgbtRed =(unsigned char)i;
  254. // 更新DIB调色板绿色分量
  255. lpbmc->bmciColors[i].rgbtGreen =(unsigned char) i;
  256. // 更新DIB调色板蓝色分量
  257. lpbmc->bmciColors[i].rgbtBlue = (unsigned char)i;
  258. }
  259. }
  260. // 找到DIB图像象素起始位置
  261. lpDIBBits = ::FindDIBBits(lpDIB);
  262. // 获取图像宽度
  263. lWidth = ::DIBWidth(lpDIB);
  264. // 获取图像高度
  265. lHeight = ::DIBHeight(lpDIB);
  266. // 计算图像每行的字节数
  267. lLineBytes = WIDTHBYTES(lWidth * 8);
  268. // 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
  269. // 每行
  270. for(i = 0; i < lHeight; i++)
  271. {
  272. // 每列
  273. for(j = 0; j < lWidth; j++)
  274. {
  275. // 指向DIB第i行,第j个象素的指针
  276. lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
  277. // 变换
  278. *lpSrc = bMap[*lpSrc];
  279. }
  280. }
  281. // 替换当前调色板为灰度调色板
  282. pDoc->GetDocPalette()->SetPaletteEntries(0, 256, (LPPALETTEENTRY) ColorsTable[0]);
  283. // 设置脏标记
  284. pDoc->SetModifiedFlag(TRUE);
  285. // 实现新的调色板
  286. OnDoRealize((WPARAM)m_hWnd,0);
  287. // 更新视图
  288. pDoc->UpdateAllViews(NULL);
  289. // 解除锁定
  290. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  291. // 恢复光标
  292. EndWaitCursor();
  293. }
  294. LRESULT CTypeRecView::OnDoRealize(WPARAM wParam, LPARAM)
  295. {
  296. ASSERT(wParam != NULL);
  297. // 获取文档
  298. CTypeRecDoc* pDoc = GetDocument();
  299. // 判断DIB是否为空
  300. if (pDoc->GetHDIB() == NULL)
  301. {
  302. // 直接返回
  303. return 0L;
  304. }
  305. // 获取Palette
  306. CPalette* pPal = pDoc->GetDocPalette();
  307. if (pPal != NULL)
  308. {
  309. // 获取MainFrame
  310. CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
  311. ASSERT_KINDOF(CMainFrame, pAppFrame);
  312. CClientDC appDC(pAppFrame);
  313. // All views but one should be a background palette.
  314. // wParam contains a handle to the active view, so the SelectPalette
  315. // bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
  316. CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);
  317. if (oldPalette != NULL)
  318. {
  319. UINT nColorsChanged = appDC.RealizePalette();
  320. if (nColorsChanged > 0)
  321. pDoc->UpdateAllViews(NULL);
  322. appDC.SelectPalette(oldPalette, TRUE);
  323. }
  324. else
  325. {
  326. TRACE0("tCCh1_1View::OnPaletteChanged中调用SelectPalette()失败!n");
  327. }
  328. }
  329. return 0L;
  330. }
  331. //24位真彩色图转换成256级灰度图
  332. //
  333. void CTypeRecView::OnFILE24ToGray()    
  334. {
  335. CTypeRecDoc* pDoc = GetDocument(); //获取文档
  336. LPSTR lpDIB;                       //指向DIB的指针
  337. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
  338. ConvertToGrayScale(lpDIB);
  339. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  340. pDoc->SetModifiedFlag(TRUE);
  341. pDoc->UpdateAllViews(NULL);
  342. }
  343. //剪裁指定区域图像
  344. //
  345. void CTypeRecView::OnTempSubrect() 
  346. {
  347. CTypeRecDoc* pDoc = GetDocument();
  348. HDIB hDIB,hNewDIB;
  349. hDIB=pDoc->GetHDIB();
  350. long lWidth;                    //图像宽度和高度
  351. long lHeight;
  352. // 指向DIB的指针
  353. LPSTR lpDIB;
  354. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  355. // 找到DIB图像象素起始位置
  356. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  357. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  358.     //假定的剪裁区域(车牌附近)
  359. //
  360. CRect rect(m_ipzLeft,m_ipzTop,m_ipzRight,m_ipzBottom);
  361. // CRect rect(m_ipzLeft,190,m_ipzRight,240);
  362. //CRect rect(0,190,lWidth,260);
  363. // CRect rect(0,m_ipzTop,lWidth,m_ipzBottom);
  364. hNewDIB= myCropDIB(hDIB,rect);
  365. if (OpenClipboard())
  366. {
  367. EmptyClipboard();
  368. SetClipboardData (CF_DIB, CopyHandle((HANDLE) hNewDIB ));
  369. CloseClipboard();
  370. }
  371. }
  372. void CTypeRecView::OnEditCopy() 
  373. {
  374. // 复制当前图像
  375. // 获取文档
  376. CTypeRecDoc* pDoc = GetDocument();
  377. // 打开剪贴板
  378. if (OpenClipboard())
  379. {
  380. // 更改光标形状
  381. BeginWaitCursor();
  382. // 清空剪贴板
  383. EmptyClipboard();
  384. // 复制当前图像到剪贴板
  385. SetClipboardData (CF_DIB, CopyHandle((HANDLE) pDoc->GetHDIB()) );
  386. // 关闭剪贴板
  387. CloseClipboard();
  388. // 恢复光标
  389. EndWaitCursor();
  390. }
  391. }
  392. void CTypeRecView::OnTempPalette() 
  393. {
  394. CDC *pDC=GetDC();
  395. // if((!pDC->GetDeviceCaps(RASTERCAPS)) & RC_PALETTE)
  396. // {
  397. // AfxMessageBox("当前显示系统不支持调色板。");
  398. // return;
  399. // }
  400. CString str;
  401. int nColorNum=pDC->GetDeviceCaps(SIZEPALETTE);
  402. str.Format("当前系统调色板可同时显示的颜色数为%d.",nColorNum);
  403. AfxMessageBox(str);
  404. int nColorReserved=pDC->GetDeviceCaps(NUMRESERVED);
  405. str.Format("当前系统调色板保留的颜色数为%d。",nColorReserved);
  406. AfxMessageBox(str);
  407. ReleaseDC(pDC);
  408. }
  409. //灰度转换测试
  410. //
  411. void CTypeRecView::OnTempGray() 
  412. {
  413. CTypeRecDoc* pDoc = GetDocument();
  414. HDIB hDIB=pDoc->GetHDIB();
  415. long lWidth;                    //图像宽度和高度
  416. long lHeight;
  417. LONG lLineBytes;
  418. // 指向DIB的指针
  419. LPSTR lpDIB;
  420. unsigned char * lpSrc;          //指向原图像象素点的指针
  421. // 指向DIB象素指针
  422. LPSTR   lpDIBBits;
  423. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  424. // 更改光标形状
  425. BeginWaitCursor();
  426. // 找到DIB图像象素起始位置
  427. lpDIBBits = ::FindDIBBits(lpDIB);
  428. // 找到DIB图像象素起始位置
  429. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  430. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  431. lLineBytes=WIDTHBYTES(lWidth*8);
  432. int i,j;
  433. for(i=0;i<lHeight;i++)
  434. for(j=0;j<lWidth;j++)
  435. {
  436. lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
  437. //if((*lpSrc)<255&&(*lpSrc)>190)
  438. if((*lpSrc)<155&&(*lpSrc)>100)
  439. *lpSrc=255;
  440. else
  441. if((*lpSrc)<255&&(*lpSrc)>190)
  442. *lpSrc=0;
  443. }
  444. pDoc->SetModifiedFlag(TRUE);
  445. pDoc->UpdateAllViews(NULL);
  446. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  447. /*
  448. // 获取文档
  449. CTypeRecDoc* pDoc = GetDocument();
  450.   // 指向DIB的指针
  451.   LPSTR lpDIB;
  452.   
  453. // 指向DIB象素指针
  454. LPSTR   lpDIBBits;
  455.   unsigned char * lpSrc;          //指向原图像象素点的指针
  456.   
  457. // 锁定DIB
  458. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
  459.   // 更改光标形状
  460.   BeginWaitCursor();
  461.   
  462. // 找到DIB图像象素起始位置
  463. lpDIBBits = ::FindDIBBits(lpDIB);
  464. long lWidth;                    //图像宽度和高度
  465. long lHeight;
  466. LONG lLineBytes;
  467.   long i,j;           //循环变量
  468.   
  469. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  470. // 找到DIB图像象素起始位置
  471. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  472. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  473.   lLineBytes=WIDTHBYTES(lWidth*8);
  474.   
  475. for(i = 0; i < lHeight; i++)
  476. {
  477. // 每列
  478. for(j =  0; j < lWidth; j++)
  479. {
  480. lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
  481. *lpSrc=0;
  482. }
  483. }
  484.   // 更改光标形状
  485.   EndWaitCursor();
  486.   
  487. pDoc->SetModifiedFlag(TRUE);
  488. pDoc->UpdateAllViews(NULL);
  489. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  490. */
  491. }
  492. void CTypeRecView::OnTempError() 
  493. {
  494. CTypeRecDoc* pDoc = GetDocument();
  495. HDIB hDIB=pDoc->GetHDIB();
  496. long lWidth;                    //图像宽度和高度
  497. long lHeight;
  498. LONG lLineBytes;
  499. // 指向DIB的指针
  500. LPSTR lpDIB;
  501. unsigned char * lpSrc;          //指向原图像象素点的指针
  502. // 指向DIB象素指针
  503. LPSTR   lpDIBBits;
  504. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  505. // 更改光标形状
  506. BeginWaitCursor();
  507. // 找到DIB图像象素起始位置
  508. lpDIBBits = ::FindDIBBits(lpDIB);
  509. // 找到DIB图像象素起始位置
  510. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  511. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  512. lLineBytes=WIDTHBYTES(lWidth*8);
  513. int i,j,pixel;
  514. long lHistogram[256];
  515. for(i=0;i<256;i++)
  516. lHistogram[i]=0;
  517. //获得直方图
  518. int iMax1GrayValue=0;
  519. int iMax2GrayValue=0;
  520. for(i=0;i<lHeight;i++)
  521. {
  522. for(j=0;j<lWidth;j++)
  523. {
  524. lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
  525. pixel=(unsigned char)(*lpSrc);
  526. lHistogram[pixel]++;
  527. }
  528. }
  529. for(i=0;i<256;i++)
  530. {
  531. //找最大灰度值点为背景灰度值
  532. if(iMax1GrayValue<lHistogram[i])
  533. {
  534. iMax1GrayValue=i;
  535. }
  536. else if(iMax2GrayValue<iMax1GrayValue&&iMax2GrayValue-1<iMax2GrayValue&&iMax2GrayValue+1<iMax2GrayValue)
  537. {
  538. iMax2GrayValue=i;
  539. }
  540. }
  541. }
  542. //用一初始阈值T对图像A进行二值化得到二值化图像B,初始阈值T的确定方法是:选择阈值
  543. //T=Gmax-(Gmax-Gmin)/3,Gmax和Gmin分别是最高、最低灰度值。
  544. //该阈值对不同牌照有一定的适应性,能够保证背景基本被置为0,以突出牌照区域
  545. //
  546. void CTypeRecView::OnTest11() 
  547. {
  548. CTypeRecDoc* pDoc=GetDocument();   //获得文档
  549. LPSTR lpDIB;                       //指向DIB的指针
  550. LPSTR lpDIBBits;                   //指向DIB的象素的指针
  551.     LONG lLineBytes;
  552. unsigned char * lpSrc;             //指向原图像象素点的指针
  553.     long lWidth;                       //图像宽度和高度
  554. long lHeight;
  555. long i,j;           //循环变量
  556. OnEditCopy();
  557. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  558. // 找到DIB图像象素起始位置
  559. lpDIBBits = ::FindDIBBits(lpDIB);
  560. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  561. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  562. // 计算图像每行的字节数
  563. lLineBytes = WIDTHBYTES(lWidth * 8);
  564. long lCount[256];
  565. for(i=0;i<256;i++)
  566. {
  567. lCount[i]=0;  //清零
  568. }
  569. if(::DIBNumColors(lpDIB) != 256)  //256色位图不作任何处理
  570. {
  571. return;
  572. }
  573. for(i=0;i<lHeight;i++)
  574. {
  575. for(j=0;j<lWidth;j++)
  576. {
  577. lpSrc=(unsigned char *)lpDIB+lLineBytes*i+j;
  578. lCount[*(lpSrc)]++;
  579. }
  580. }
  581. //求窗口变换的上限和下限
  582. //
  583. long temp[16];
  584. int k=0;
  585. for(k=0;k<16;k++)
  586. {
  587. temp[k]=0;
  588. for(i=k*16;i<(k+1)*16;i++)
  589. temp[k]+=lCount[i];
  590. }
  591. long max=0;
  592. int t=0;
  593. for(k=15;k>=0;k--)
  594. {
  595. if(temp[k]>max)
  596. {
  597. max=temp[k];
  598. t=k;
  599. }
  600. }
  601. int bLow=0,bUp=0;
  602. bLow=(t-1)*16;
  603. // bUp=(t+5)*16;
  604. // bLow=100;
  605. bUp=255;
  606. // 阈值
  607. INT bThre;
  608. bThre=(INT)((2*bUp+bLow)/3);
  609. // 更改光标形状
  610. BeginWaitCursor();
  611. // 调用ThresholdTrans()函数进行阈值变换
  612. ThresholdTrans(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB), bThre);
  613. pDoc->SetModifiedFlag(TRUE);
  614. pDoc->UpdateAllViews(NULL);
  615. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  616. // 恢复光标
  617. EndWaitCursor();
  618. }
  619. //(2)削弱背景干扰。对图像B作简单的相邻像素灰度值相减,得到新的图像G,
  620. //即Gi,j=|Pi,j-Pi,j-1|i=0,1,…,439;j=0,1,…,639Gi,0=Pi,0,左边缘直接赋值,
  621. //不会影响整体效果。
  622. //
  623. void CTypeRecView::OnTest12() 
  624. {
  625. CTypeRecDoc* pDoc=GetDocument();   //获得文档
  626. LPSTR lpDIB;                       //指向DIB的指针
  627. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  628. //用自定义的模板消弱背景干扰
  629. myTemplate(lpDIB);
  630. pDoc->SetModifiedFlag(TRUE);
  631. pDoc->UpdateAllViews(NULL);
  632. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  633. }
  634. //区域灰度基本被赋值为0(图2(f))。考虑到文字是由许多短竖线组成,
  635. //而背景噪声有一大部分是孤立噪声,用模板(1,1,1,1,1)T对G进行中值滤波,
  636. //得到除掉了大部分干扰的图像C。
  637. //
  638. void CTypeRecView::OnTest13() 
  639. {
  640. // 中值滤波
  641. // 获取文档
  642. CTypeRecDoc* pDoc = GetDocument();
  643. // 指向DIB的指针
  644. LPSTR lpDIB;
  645. // 指向DIB象素指针
  646. LPSTR   lpDIBBits;
  647. // 滤波器的高度
  648. int iFilterH;
  649. // 滤波器的宽度
  650. int iFilterW;
  651. // 中心元素的X坐标
  652. int iFilterMX;
  653. // 中心元素的Y坐标
  654. int iFilterMY;
  655. // 锁定DIB
  656. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());
  657. // 找到DIB图像象素起始位置
  658. lpDIBBits = ::FindDIBBits(lpDIB);
  659. // 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的中值滤波,其它的可以类推)
  660. if (::DIBNumColors(lpDIB) != 256)
  661. {
  662. // 提示用户
  663. MessageBox("目前只支持256色位图的中值滤波!", "系统提示" ,
  664. MB_ICONINFORMATION | MB_OK);
  665. // 解除锁定
  666. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  667. // 返回
  668. return;
  669. }
  670. // 创建对话框
  671. // 初始化变量值
  672. iFilterH = 5;
  673. iFilterW = 1;
  674. iFilterMX = 0;
  675. iFilterMY = 2;
  676. // 更改光标形状
  677. BeginWaitCursor();
  678. // 调用MedianFilter()函数中值滤波
  679. if (myMedianFilter(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB), 
  680. iFilterH, iFilterW, iFilterMX, iFilterMY))
  681. {
  682. // 设置脏标记
  683. pDoc->SetModifiedFlag(TRUE);
  684. // 更新视图
  685. pDoc->UpdateAllViews(NULL);
  686. }
  687. else
  688. {
  689. // 提示用户
  690. MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK);
  691. }
  692. // 解除锁定
  693. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  694. // 恢复光标
  695. EndWaitCursor();
  696. }
  697. //利用水平投影法检测车牌水平位置
  698. //
  699. void CTypeRecView::OnTest14() 
  700. {
  701. CTypeRecDoc* pDoc=GetDocument();   //获得文档
  702. LPSTR lpDIB;                       //指向DIB的指针
  703.     long lWidth;                       //图像宽度和高度
  704. long lHeight;
  705. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  706. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  707. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  708. //水平投影,求取车牌子图像的上下边缘位置
  709. //
  710. myHprojectDIB(lpDIB, lWidth, lHeight,&m_ipzTop, &m_ipzBottom) ;
  711. m_ipzLeft=0;
  712. m_ipzRight=lWidth;
  713. pDoc->UpdateAllViews(NULL);
  714. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  715. //对含车牌图像进行剪裁,得到车牌高度,原图像宽度的图像
  716. OnTempSubrect();
  717. }
  718. //利用垂直投影法检测车牌垂直位置
  719. //
  720. void CTypeRecView::OnTest15() 
  721. {
  722. CTypeRecDoc* pDoc=GetDocument();   //获得文档
  723. LPSTR lpDIB;                       //指向DIB的指针
  724.     long lWidth;                       //图像宽度和高度
  725. long lHeight;
  726. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  727. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  728. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  729. myVprojectDIB(lpDIB, lWidth, lHeight,&m_ipzLeft, &m_ipzRight) ;
  730. pDoc->UpdateAllViews(NULL);
  731. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  732. OnTempSubrect();
  733. }
  734. void CTypeRecView::OnEditPaste() 
  735. {
  736. // 粘贴图像
  737. // 创建新DIB
  738. HDIB hNewDIB = NULL;
  739. // 打开剪贴板
  740. if (OpenClipboard())
  741. {
  742. // 更改光标形状
  743. BeginWaitCursor();
  744. // 读取剪贴板中的图像
  745. hNewDIB = (HDIB) CopyHandle(::GetClipboardData(CF_DIB));
  746. // 关闭剪贴板
  747. CloseClipboard();
  748. // 判断是否读取成功
  749. if (hNewDIB != NULL)
  750. {
  751. // 获取文档
  752. CTypeRecDoc* pDoc = GetDocument();
  753. // 替换DIB,同时释放旧DIB对象
  754. pDoc->ReplaceHDIB(hNewDIB);
  755. // 更新DIB大小和调色板
  756. pDoc->InitDIBData();
  757. // 设置脏标记
  758. pDoc->SetModifiedFlag(TRUE);
  759. // 重新设置滚动视图大小
  760. // SetScrollSizes(MM_TEXT, pDoc->GetDocSize());
  761. // 实现新的调色板
  762. OnDoRealize((WPARAM)m_hWnd,0);
  763. // 更新视图
  764. pDoc->UpdateAllViews(NULL);
  765. }
  766. // 恢复光标
  767. EndWaitCursor();
  768. }
  769. }
  770. //综合第4,5步骤
  771. //
  772. void CTypeRecView::OnTest145() 
  773. {
  774. CTypeRecDoc* pDoc=GetDocument();   //获得文档
  775. LPSTR lpDIB;                       //指向DIB的指针
  776.     long lWidth;                       //图像宽度和高度
  777. long lHeight;
  778. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  779. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  780. lHeight = ::DIBHeight(lpDIB); //DIB 高度
  781. //水平投影,求取车牌子图像的上下边缘位置
  782. //
  783. myHprojectDIB(lpDIB, lWidth, lHeight,&m_ipzTop, &m_ipzBottom) ;
  784. m_ipzLeft=0;
  785. m_ipzRight=lWidth;
  786. //对含车牌图像进行剪裁,得到车牌高度,原图像宽度的图像
  787. // OnTempSubrect();
  788. HDIB hDIB;
  789. HDIB hNewDIB;
  790. hDIB=pDoc->GetHDIB();
  791.     //假定的剪裁区域(车牌附近)
  792. //
  793. CRect rect(m_ipzLeft,m_ipzTop,m_ipzRight,m_ipzBottom);
  794. hNewDIB= myCropDIB(hDIB,rect);
  795. // 判断是否剪裁成功
  796. if (hNewDIB != NULL)
  797. {
  798. // 获取文档
  799. CTypeRecDoc* pDoc = GetDocument();
  800. // 替换DIB,同时释放旧DIB对象
  801. pDoc->ReplaceHDIB(hNewDIB);
  802. // 更新DIB大小和调色板
  803. pDoc->InitDIBData();
  804. // 设置脏标记
  805. pDoc->SetModifiedFlag(TRUE);
  806. // 实现新的调色板
  807. OnDoRealize((WPARAM)m_hWnd,0);
  808. }
  809. //5
  810. lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB());//获得当前位图
  811. lWidth = ::DIBWidth(lpDIB);   //DIB 宽度
  812. lHeight =::DIBHeight(lpDIB); //DIB 高度
  813. myVprojectDIB(lpDIB, lWidth, lHeight,&m_ipzLeft, &m_ipzRight) ;
  814. pDoc->UpdateAllViews(NULL);
  815. ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
  816. }
  817. //截取车牌子图像
  818. //
  819. void CTypeRecView::OnTest16() 
  820. {
  821. OnEditPaste();
  822. OnTempSubrect();
  823. OnEditPaste();
  824. }