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

图片显示

开发平台:

Visual C++

  1. // DlgHistogram.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "QuickImage.h"
  5. #include "DlgHistogram.h"
  6. #include <math.h>
  7. #include "image.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CDlgHistogram dialog
  15. CDlgHistogram::CDlgHistogram(HDIB hDIB, CWnd* pParent /*=NULL*/)
  16. : CDialog(CDlgHistogram::IDD, pParent), m_hDIB(hDIB)
  17. {
  18. //{{AFX_DATA_INIT(CDlgHistogram)
  19. // NOTE: the ClassWizard will add member initialization here
  20. //}}AFX_DATA_INIT
  21. m_iPixels = m_iColors = 0;
  22. m_dStdDev = m_dMean = 0.0;
  23. m_iMin = UINT_MAX;
  24. m_iMax = 0;
  25. m_dShang = 0.0;
  26. m_rcHist = CRect(0,0,0,0);
  27. m_iStart = m_iEnd = 0;
  28. for(int i=0; i< 256; i++)
  29. {
  30. m_iHistogram[i] = 0;
  31. m_iRed[i] = 0;
  32. m_iGreen[i] = 0;
  33. m_iBlue[i] = 0;
  34. }
  35. }
  36. void CDlgHistogram::DoDataExchange(CDataExchange* pDX)
  37. {
  38. CDialog::DoDataExchange(pDX);
  39. //{{AFX_DATA_MAP(CDlgHistogram)
  40. // NOTE: the ClassWizard will add DDX and DDV calls here
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CDlgHistogram, CDialog)
  44. //{{AFX_MSG_MAP(CDlgHistogram)
  45. ON_WM_PAINT()
  46. ON_WM_MOUSEMOVE()
  47. ON_WM_LBUTTONDOWN()
  48. ON_WM_LBUTTONUP()
  49. ON_WM_CTLCOLOR()
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CDlgHistogram message handlers
  54. void CDlgHistogram::OnPaint() 
  55. {
  56. CPaintDC dc(this); // device context for painting
  57. DrawHistogram(&dc);
  58. // Do not call CDialog::OnPaint() for painting messages
  59. }
  60. BOOL CDlgHistogram::OnInitDialog() 
  61. {
  62. CDialog::OnInitDialog();
  63. m_btOK.SubclassDlgItem(IDOK, this);
  64. m_btOK.SetIcon(IDI_OKAC, IDI_OKUN);
  65. m_btOK.SetActiveBgColor(RGB(220,220,220));
  66. m_btOK.SetActiveFgColor(RGB(255,0,0));
  67. m_btOK.SetBtnCursor(IDC_GREEN);
  68. if (m_hDIB != NULL)
  69. {
  70. LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
  71. m_iPixels = ::DIBWidth(lpDIB) * abs(::DIBHeight(lpDIB));
  72. m_iColors = DIBNumColors(lpDIB);
  73. LPSTR lpBits = FindDIBBits(lpDIB);
  74. CImage::Properties(m_iHistogram, m_dMean, m_dStdDev, m_dShang,
  75. lpBits, m_iPixels, m_iColors);
  76. ::GlobalUnlock((HGLOBAL) m_hDIB);
  77. for(int i = 0; i < 256; i++)
  78. {
  79. if(m_iHistogram[i] < m_iMin)
  80. {
  81. m_iMin = m_iHistogram[i];
  82. }
  83. else if(m_iHistogram[i] > m_iMax)
  84. {
  85. m_iMax = m_iHistogram[i];
  86. }
  87. }
  88. }
  89. CWnd *pWnd = NULL;
  90. // if(m_iColors > 0)
  91. {
  92. pWnd = GetDlgItem(IDC_COMBO_CHANNEL);
  93. ASSERT(NULL != pWnd);
  94. ((CComboBox *)pWnd)->Clear();
  95. ((CComboBox *)pWnd)->AddString("All Channels");
  96. if(m_iColors > 8)
  97. {
  98. ((CComboBox *)pWnd)->AddString("Red Channels");
  99. ((CComboBox *)pWnd)->AddString("Green Channels");
  100. ((CComboBox *)pWnd)->AddString("Blue Channels");
  101. }
  102. ((CComboBox *)pWnd)->SetCurSel(0);
  103. }
  104. char strText[20];
  105. pWnd = GetDlgItem(IDC_HISTOGRAM_PIXELS);
  106. ASSERT(NULL != pWnd);
  107. sprintf(strText, "Pixels: %d", m_iPixels);
  108. pWnd->SetWindowText(strText);
  109. pWnd = GetDlgItem(IDC_HISTOGRAM_MEAN);
  110. ASSERT(NULL != pWnd);
  111. sprintf(strText, "Mean: %.1f", m_dMean);
  112. pWnd->SetWindowText(strText);
  113. pWnd = GetDlgItem(IDC_HISTOGRAM_DEV);
  114. ASSERT(NULL != pWnd);
  115. sprintf(strText, "Std Dev: %.1f", m_dStdDev);
  116. pWnd->SetWindowText(strText);
  117. pWnd = GetDlgItem(IDC_HISTOGRAM_SHANG);
  118. ASSERT(NULL != pWnd);
  119. sprintf(strText, "Entropy : %.1f", m_dShang);
  120. pWnd->SetWindowText(strText);
  121. pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
  122. ASSERT(NULL != pWnd);
  123. sprintf(strText, "Level:");
  124. pWnd->SetWindowText(strText);
  125. pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
  126. ASSERT(NULL != pWnd);
  127. sprintf(strText, "Count:");
  128. pWnd->SetWindowText(strText);
  129. pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
  130. ASSERT(NULL != pWnd);
  131. sprintf(strText, "Percent:");
  132. pWnd->SetWindowText(strText);
  133. GetClientRect(&m_rcHist);
  134. CRect rcTag;
  135. pWnd = GetDlgItem(IDC_STATIC);
  136. ASSERT(NULL != pWnd);
  137. pWnd->GetClientRect(&rcTag);
  138. m_rcHist.bottom -= (rcTag.Height() + 6);
  139. int iWid = (m_rcHist.Width() - rcTag.Width())/2;
  140. m_rcHist.left += iWid;
  141. m_rcHist.right -= iWid;
  142. return TRUE;  // return TRUE unless you set the focus to a control
  143. // EXCEPTION: OCX Property Pages should return FALSE
  144. }
  145. void CDlgHistogram::DrawHistogram(CDC *pDC)
  146. {
  147. CBrush *pbrOld = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
  148. pDC->Rectangle(m_rcHist);
  149. // LPSTR lpBits = (LPSTR)GlobalLock(m_hDIB);
  150. double dx = m_rcHist.Width() / 255.0;
  151. double dy = m_rcHist.Height() / (double)m_iMax;
  152. // dy = (double)m_rcHist.Width()/::DIBWidth(lpBits) * m_rcHist.Height()/abs(::DIBHeight(lpBits)) * 2.0;
  153. // GlobalUnlock(m_hDIB);
  154. int x, y;
  155. for (int i =0; i< 255; i++)
  156. {
  157. x = m_rcHist.left + int(i * dx);
  158. y = m_rcHist.bottom - int(m_iHistogram[i] * dy);
  159. pDC->Rectangle(x, y, x + (int)dx + 1, m_rcHist.bottom);
  160. }
  161. x = m_rcHist.right - int(dx * 2.0);
  162. pDC->Rectangle(x, m_rcHist.bottom - int(m_iHistogram[255] * dy),
  163. m_rcHist.right, m_rcHist.bottom);
  164. CPen  penRed;
  165. penRed.CreatePen(PS_SOLID, 0, RGB(255,0,0));
  166. CPen *ppenOld = (CPen*)pDC->SelectObject(&penRed);
  167. CBrush brRed;
  168. brRed.CreateSolidBrush(RGB(255,0,0));
  169. pDC->SelectObject(&brRed);
  170. int iOldROP = pDC->SetROP2(R2_XORPEN);
  171. pDC->Rectangle(m_rcHist.left + int(m_iStart * dx), m_rcHist.top,
  172. m_rcHist.left + int(m_iEnd * dx), m_rcHist.bottom);
  173. pDC->SetROP2(iOldROP);
  174. pDC->SelectObject(ppenOld);
  175. pDC->SelectObject(pbrOld);
  176. }
  177. void CDlgHistogram::OnMouseMove(UINT nFlags, CPoint point) 
  178. {
  179. if(nFlags & MK_LBUTTON)
  180. {
  181. if(point.x > m_rcHist.left && point.x < m_rcHist.right
  182. && point.y > m_rcHist.top && point.y < m_rcHist.bottom)
  183. {
  184. double dx = m_rcHist.Width()/255.0;
  185. int x1 = m_rcHist.left + int(m_iEnd * dx);
  186. m_iEnd = BYTE(double(point.x - m_rcHist.left) * 255.0 / m_rcHist.Width() + 0.5);
  187. int x2 = m_rcHist.left + int(m_iEnd * dx);
  188. InvalidateRect(CRect(x1, m_rcHist.top, x2, m_rcHist.bottom));
  189. char strText[20];
  190. CWnd *pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
  191. ASSERT(NULL != pWnd);
  192. sprintf(strText, "Level: %d...%d", m_iStart, m_iEnd);
  193. pWnd->SetWindowText(strText);
  194. pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
  195. ASSERT(NULL != pWnd);
  196. x1 = 0;
  197. if(m_iEnd > m_iStart)
  198. {
  199. for(x2 = m_iStart; x2 < m_iEnd + 1; x2++)
  200. {
  201. x1 += m_iHistogram[x2];
  202. }
  203. }
  204. else
  205. {
  206. for(x2 = m_iStart; x2 > m_iEnd - 1; x2--)
  207. {
  208. x1 += m_iHistogram[x2];
  209. }
  210. }
  211. sprintf(strText, "Count: %d", x1);
  212. pWnd->SetWindowText(strText);
  213. pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
  214. ASSERT(NULL != pWnd);
  215. sprintf(strText, "Percent: %.1f", (double)x1 * 100.0/m_iPixels);
  216. pWnd->SetWindowText(strText);
  217. }
  218. }
  219. CDialog::OnMouseMove(nFlags, point);
  220. }
  221. void CDlgHistogram::OnLButtonDown(UINT nFlags, CPoint point) 
  222. {
  223. if(point.x > m_rcHist.left && point.x < m_rcHist.right
  224. && point.y > m_rcHist.top && point.y < m_rcHist.bottom)
  225. {
  226. m_iStart = (BYTE)(double(point.x - m_rcHist.left)/m_rcHist.Width() * 255.0);
  227. }
  228. CDialog::OnLButtonDown(nFlags, point);
  229. }
  230. void CDlgHistogram::OnLButtonUp(UINT nFlags, CPoint point) 
  231. {
  232. double dx = m_rcHist.Width()/255.0;
  233. int x1 = m_rcHist.left + int(m_iStart * dx);
  234. int x2 = m_rcHist.left + int(m_iEnd * dx);
  235. InvalidateRect(CRect(x1, m_rcHist.top, x2, m_rcHist.bottom));
  236. m_iStart = m_iEnd = 0;
  237. char strText[20];
  238. CWnd *pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
  239. ASSERT(NULL != pWnd);
  240. sprintf(strText, "Level:");
  241. pWnd->SetWindowText(strText);
  242. pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
  243. ASSERT(NULL != pWnd);
  244. sprintf(strText, "Count:");
  245. pWnd->SetWindowText(strText);
  246. pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
  247. ASSERT(NULL != pWnd);
  248. sprintf(strText, "Percent:");
  249. pWnd->SetWindowText(strText);
  250. CDialog::OnLButtonUp(nFlags, point);
  251. }
  252. HBRUSH CDlgHistogram::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
  253. {
  254. HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  255. if(nCtlColor == CTLCOLOR_STATIC)
  256. pDC->SetTextColor(RGB(0,96,249));
  257. // TODO: Return a different brush if the default is not desired
  258. return hbr;
  259. }