📄 dlghistogram.cpp
字号:
// DlgHistogram.cpp : implementation file
//
#include "stdafx.h"
#include "QuickImage.h"
#include "DlgHistogram.h"
#include <math.h>
#include "image.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDlgHistogram dialog
CDlgHistogram::CDlgHistogram(HDIB hDIB, CWnd* pParent /*=NULL*/)
: CDialog(CDlgHistogram::IDD, pParent), m_hDIB(hDIB)
{
//{{AFX_DATA_INIT(CDlgHistogram)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_iPixels = m_iColors = 0;
m_dStdDev = m_dMean = 0.0;
m_iMin = UINT_MAX;
m_iMax = 0;
m_dShang = 0.0;
m_rcHist = CRect(0,0,0,0);
m_iStart = m_iEnd = 0;
for(int i=0; i< 256; i++)
{
m_iHistogram[i] = 0;
m_iRed[i] = 0;
m_iGreen[i] = 0;
m_iBlue[i] = 0;
}
}
void CDlgHistogram::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgHistogram)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgHistogram, CDialog)
//{{AFX_MSG_MAP(CDlgHistogram)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgHistogram message handlers
void CDlgHistogram::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawHistogram(&dc);
// Do not call CDialog::OnPaint() for painting messages
}
BOOL CDlgHistogram::OnInitDialog()
{
CDialog::OnInitDialog();
m_btOK.SubclassDlgItem(IDOK, this);
m_btOK.SetIcon(IDI_OKAC, IDI_OKUN);
m_btOK.SetActiveBgColor(RGB(220,220,220));
m_btOK.SetActiveFgColor(RGB(255,0,0));
m_btOK.SetBtnCursor(IDC_GREEN);
if (m_hDIB != NULL)
{
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
m_iPixels = ::DIBWidth(lpDIB) * abs(::DIBHeight(lpDIB));
m_iColors = DIBNumColors(lpDIB);
LPSTR lpBits = FindDIBBits(lpDIB);
CImage::Properties(m_iHistogram, m_dMean, m_dStdDev, m_dShang,
lpBits, m_iPixels, m_iColors);
::GlobalUnlock((HGLOBAL) m_hDIB);
for(int i = 0; i < 256; i++)
{
if(m_iHistogram[i] < m_iMin)
{
m_iMin = m_iHistogram[i];
}
else if(m_iHistogram[i] > m_iMax)
{
m_iMax = m_iHistogram[i];
}
}
}
CWnd *pWnd = NULL;
// if(m_iColors > 0)
{
pWnd = GetDlgItem(IDC_COMBO_CHANNEL);
ASSERT(NULL != pWnd);
((CComboBox *)pWnd)->Clear();
((CComboBox *)pWnd)->AddString("All Channels");
if(m_iColors > 8)
{
((CComboBox *)pWnd)->AddString("Red Channels");
((CComboBox *)pWnd)->AddString("Green Channels");
((CComboBox *)pWnd)->AddString("Blue Channels");
}
((CComboBox *)pWnd)->SetCurSel(0);
}
char strText[20];
pWnd = GetDlgItem(IDC_HISTOGRAM_PIXELS);
ASSERT(NULL != pWnd);
sprintf(strText, "Pixels: %d", m_iPixels);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_MEAN);
ASSERT(NULL != pWnd);
sprintf(strText, "Mean: %.1f", m_dMean);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_DEV);
ASSERT(NULL != pWnd);
sprintf(strText, "Std Dev: %.1f", m_dStdDev);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_SHANG);
ASSERT(NULL != pWnd);
sprintf(strText, "Entropy : %.1f", m_dShang);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
ASSERT(NULL != pWnd);
sprintf(strText, "Level:");
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
ASSERT(NULL != pWnd);
sprintf(strText, "Count:");
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
ASSERT(NULL != pWnd);
sprintf(strText, "Percent:");
pWnd->SetWindowText(strText);
GetClientRect(&m_rcHist);
CRect rcTag;
pWnd = GetDlgItem(IDC_STATIC);
ASSERT(NULL != pWnd);
pWnd->GetClientRect(&rcTag);
m_rcHist.bottom -= (rcTag.Height() + 6);
int iWid = (m_rcHist.Width() - rcTag.Width())/2;
m_rcHist.left += iWid;
m_rcHist.right -= iWid;
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CDlgHistogram::DrawHistogram(CDC *pDC)
{
CBrush *pbrOld = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
pDC->Rectangle(m_rcHist);
// LPSTR lpBits = (LPSTR)GlobalLock(m_hDIB);
double dx = m_rcHist.Width() / 255.0;
double dy = m_rcHist.Height() / (double)m_iMax;
// dy = (double)m_rcHist.Width()/::DIBWidth(lpBits) * m_rcHist.Height()/abs(::DIBHeight(lpBits)) * 2.0;
// GlobalUnlock(m_hDIB);
int x, y;
for (int i =0; i< 255; i++)
{
x = m_rcHist.left + int(i * dx);
y = m_rcHist.bottom - int(m_iHistogram[i] * dy);
pDC->Rectangle(x, y, x + (int)dx + 1, m_rcHist.bottom);
}
x = m_rcHist.right - int(dx * 2.0);
pDC->Rectangle(x, m_rcHist.bottom - int(m_iHistogram[255] * dy),
m_rcHist.right, m_rcHist.bottom);
CPen penRed;
penRed.CreatePen(PS_SOLID, 0, RGB(255,0,0));
CPen *ppenOld = (CPen*)pDC->SelectObject(&penRed);
CBrush brRed;
brRed.CreateSolidBrush(RGB(255,0,0));
pDC->SelectObject(&brRed);
int iOldROP = pDC->SetROP2(R2_XORPEN);
pDC->Rectangle(m_rcHist.left + int(m_iStart * dx), m_rcHist.top,
m_rcHist.left + int(m_iEnd * dx), m_rcHist.bottom);
pDC->SetROP2(iOldROP);
pDC->SelectObject(ppenOld);
pDC->SelectObject(pbrOld);
}
void CDlgHistogram::OnMouseMove(UINT nFlags, CPoint point)
{
if(nFlags & MK_LBUTTON)
{
if(point.x > m_rcHist.left && point.x < m_rcHist.right
&& point.y > m_rcHist.top && point.y < m_rcHist.bottom)
{
double dx = m_rcHist.Width()/255.0;
int x1 = m_rcHist.left + int(m_iEnd * dx);
m_iEnd = BYTE(double(point.x - m_rcHist.left) * 255.0 / m_rcHist.Width() + 0.5);
int x2 = m_rcHist.left + int(m_iEnd * dx);
InvalidateRect(CRect(x1, m_rcHist.top, x2, m_rcHist.bottom));
char strText[20];
CWnd *pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
ASSERT(NULL != pWnd);
sprintf(strText, "Level: %d...%d", m_iStart, m_iEnd);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
ASSERT(NULL != pWnd);
x1 = 0;
if(m_iEnd > m_iStart)
{
for(x2 = m_iStart; x2 < m_iEnd + 1; x2++)
{
x1 += m_iHistogram[x2];
}
}
else
{
for(x2 = m_iStart; x2 > m_iEnd - 1; x2--)
{
x1 += m_iHistogram[x2];
}
}
sprintf(strText, "Count: %d", x1);
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
ASSERT(NULL != pWnd);
sprintf(strText, "Percent: %.1f", (double)x1 * 100.0/m_iPixels);
pWnd->SetWindowText(strText);
}
}
CDialog::OnMouseMove(nFlags, point);
}
void CDlgHistogram::OnLButtonDown(UINT nFlags, CPoint point)
{
if(point.x > m_rcHist.left && point.x < m_rcHist.right
&& point.y > m_rcHist.top && point.y < m_rcHist.bottom)
{
m_iStart = (BYTE)(double(point.x - m_rcHist.left)/m_rcHist.Width() * 255.0);
}
CDialog::OnLButtonDown(nFlags, point);
}
void CDlgHistogram::OnLButtonUp(UINT nFlags, CPoint point)
{
double dx = m_rcHist.Width()/255.0;
int x1 = m_rcHist.left + int(m_iStart * dx);
int x2 = m_rcHist.left + int(m_iEnd * dx);
InvalidateRect(CRect(x1, m_rcHist.top, x2, m_rcHist.bottom));
m_iStart = m_iEnd = 0;
char strText[20];
CWnd *pWnd = GetDlgItem(IDC_HISTOGRAM_LEVEL);
ASSERT(NULL != pWnd);
sprintf(strText, "Level:");
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_COUNT);
ASSERT(NULL != pWnd);
sprintf(strText, "Count:");
pWnd->SetWindowText(strText);
pWnd = GetDlgItem(IDC_HISTOGRAM_PERCENT);
ASSERT(NULL != pWnd);
sprintf(strText, "Percent:");
pWnd->SetWindowText(strText);
CDialog::OnLButtonUp(nFlags, point);
}
HBRUSH CDlgHistogram::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(nCtlColor == CTLCOLOR_STATIC)
pDC->SetTextColor(RGB(0,96,249));
// TODO: Return a different brush if the default is not desired
return hbr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -