www.pudn.com > partsumhist.rar > HistogramDlg.cpp
// HistogramDlg.cpp : implementation file
//
#include "stdafx.h"
#include "practice.h"
#include "HistogramDlg.h"
#include "HSI.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern RGB* g_pImgBuffer;
extern int g_nMapHeight;
extern int g_nMapWidth;
extern FLAGS* g_pFlags;
/////////////////////////////////////////////////////////////////////////////
// CHistogramDlg dialog
CHistogramDlg::CHistogramDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHistogramDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHistogramDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CHistogramDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHistogramDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CHistogramDlg, CDialog)
//{{AFX_MSG_MAP(CHistogramDlg)
ON_BN_CLICKED(IDC_red, Onred)
ON_BN_CLICKED(IDC_green, Ongreen)
ON_BN_CLICKED(IDC_blue, Onblue)
ON_BN_CLICKED(IDC_mean, Onmean)
ON_BN_CLICKED(IDC_sumhist, Onsumhist)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHistogramDlg message handlers
BEGIN_EVENTSINK_MAP(CHistogramDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CHistogramDlg)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
BOOL CHistogramDlg::OnInitDialog(void)
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
if(!g_hBitmap)
MessageBox("图像文件错误!无法生成柱状图.");
else
{
GenHistogramData();
((CButton *) GetDlgItem(IDC_red))->SetCheck(true);
CWnd *Chart;
Chart = GetDlgItem(IDC_histogram_chart);
Chart->GetWindowRect(&m_ChartRect);
ScreenToClient(&m_ChartRect);
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CHistogramDlg::Onred(void)
{
// TODO: Add your control notification handler code here
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
void CHistogramDlg::Ongreen(void)
{
// TODO: Add your control notification handler code here
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
void CHistogramDlg::Onblue(void)
{
// TODO: Add your control notification handler code here
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
void CHistogramDlg::Onmean(void)
{
// TODO: Add your control notification handler code here
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
void CHistogramDlg::Onsumhist(void)
{
// TODO: Add your control notification handler code here
UpdateData(FALSE);
InvalidateRect(0, TRUE);
}
void CHistogramDlg::GenHistogramData(void)
{
RGB *cur=g_pImgBuffer;
FLAGS *cur_flag=g_pFlags;
memset(m_Histogram, 0, sizeof(m_Histogram));
for(int j = 0; j < g_nMapHeight; j++)
{
for(int i = 0; i < g_nMapWidth; i++)
{
m_Histogram[0][cur->r]++;
m_Histogram[1][cur->g]++;
m_Histogram[2][cur->b]++;
cur_flag++;
cur++;
}
}
DWORD maxr = 0, maxg = 0, maxb = 0;
double tot_pixel = g_nMapWidth * g_nMapHeight;
for(int i = 0; i < 256; i++)
{
if(maxr < m_Histogram[0][i]) maxr = m_Histogram[0][i];
if(maxg < m_Histogram[1][i]) maxg = m_Histogram[1][i];
if(maxb < m_Histogram[2][i]) maxb = m_Histogram[2][i];
}
ratior = tot_pixel / maxr;
ratiog = tot_pixel / maxg;
ratiob = tot_pixel / maxb;
for(i = 0; i < 256; i++)
{
m_Histogram[0][i] = (long) ((m_Histogram[0][i] * 10.0 * ratior) / tot_pixel);
m_Histogram[1][i] = (long) ((m_Histogram[1][i] * 100.0 * ratiog) / tot_pixel);
m_Histogram[2][i] = (long) ((m_Histogram[2][i] * 100.0 * ratiob) / tot_pixel);
if(m_Histogram[0][i] > 101) m_Histogram[0][i] = 101;
if(m_Histogram[1][i] > 101) m_Histogram[1][i] = 101;
if(m_Histogram[2][i] > 101) m_Histogram[2][i] = 101;
}
//generate mean
for(int k = 0; k < 256; k++)
{
m_Histogram[3][k] = (long)(0.3*m_Histogram[0][k]+0.59*m_Histogram[1][k]+0.11*m_Histogram[2][k]);
}
//generate sumhist
for(int a = 0; a < 32; a++)
{
m_Histogram[4][-1] =0;
m_Histogram[4][a] =m_Histogram[4][a-1]+m_Histogram[0][a];
}
for(int b = 32; b < 64; b++)
{
m_Histogram[4][31]=0;
m_Histogram[4][b] =m_Histogram[4][b-1]+m_Histogram[0][b];
}
for(int c = 64; c < 96; c++)
{
m_Histogram[4][63]=0;
m_Histogram[4][c] =m_Histogram[4][c-1]+m_Histogram[0][c];
}
for(int d = 96; d < 128; d++)
{
m_Histogram[4][95]=0;
m_Histogram[4][d] =m_Histogram[4][d-1]+m_Histogram[0][d];
}
for(int e = 128; e < 160; e++)
{
m_Histogram[4][127]=0;
m_Histogram[4][e] =m_Histogram[4][e-1]+m_Histogram[0][e];
}
for(int f = 160; f < 192; f++)
{
m_Histogram[4][159]=0;
m_Histogram[4][f] =m_Histogram[4][f-1]+m_Histogram[0][f];
}
for(int g = 192; g < 224; g++)
{
m_Histogram[4][191]=0;
m_Histogram[4][g] =m_Histogram[4][g-1]+m_Histogram[0][g];
}
for(int h = 224; h < 256; h++)
{
m_Histogram[4][223]=0;
m_Histogram[4][h] =m_Histogram[4][h-1]+m_Histogram[0][h];
}
}
void CHistogramDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
if(((CButton *) GetDlgItem(IDC_red))->GetCheck())
{
DrawData(&dc, 0); // red
}
else if(((CButton *) GetDlgItem(IDC_green))->GetCheck())
{
DrawData(&dc, 1); // green
}
else if(((CButton *) GetDlgItem(IDC_blue))->GetCheck())
{
DrawData(&dc, 2); // blue
}
// paint mean
else if(((CButton *) GetDlgItem(IDC_mean))->GetCheck())
{
DrawData(&dc, 3);
}
// paint sumhist
else if(((CButton *) GetDlgItem(IDC_sumhist))->GetCheck())
{
DrawData(&dc, 4);
}
else
MessageBox("unknown error");
// Do not call CDialog::OnPaint() for painting messages
}
void CHistogramDlg::DrawData(CDC *dc, char type)
{
int i;
CPen pen;
switch(type)
{
case 0:
pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
dc->SelectObject(pen);
for(i = 0; i < 256; i++)
{
dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[0][i] * 2);
}
DeleteObject(pen);
break;
case 1:
pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
dc->SelectObject(pen);
for(i = 0; i < 256; i++)
{
dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[1][i] * 2);
}
DeleteObject(pen);
break;
case 2:
pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
dc->SelectObject(pen);
for(i = 0; i < 256; i++)
{
dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[2][i] * 2);
}
DeleteObject(pen);
break;
// paint mean
case 3:
pen.CreatePen(PS_SOLID,1,RGB(128,128,128));
dc->SelectObject(pen);
for(i = 0; i < 256; i++)
{
dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[3][i] * 2);
}
DeleteObject(pen);
break;
// paint sumhist
case 4:
pen.CreatePen(PS_SOLID,1,RGB(255,0,0));
dc->SelectObject(pen);
for(i = 0; i < 256; i++)
{
dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[4][i] * 2);
}
DeleteObject(pen);
break;
}
}