bmp位图保存方法、灰度拉伸、直方图均衡化和水波纹模拟

本文介绍了一个图像处理应用程序的实现细节,包括如何通过不同的算法进行灰度转换、二值化处理、图像翻转、直方图均衡化等操作,并展示了如何使用滑动条来调整图像的对比度和亮度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#if !defined(AFX_WAVEDLG_H__3AD6300B_435E_4773_8C88_DDE56BEE2A52__INCLUDED_)
#define AFX_WAVEDLG_H__3AD6300B_435E_4773_8C88_DDE56BEE2A52__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

/////////////////////////////////////////////////////////////////////////////
// CWaveDlg dialog

class CWaveDlg : public CDialog
{
// Construction
public:
CWaveDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
//{{AFX_DATA(CWaveDlg)
enum { IDD = IDD_WAVE_DIALOG };
CSliderCtrl	m_slider2;
CSliderCtrl	m_sliderCtr;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CWaveDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
//}}AFX_VIRTUAL


// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CWaveDlg)

virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnStaticWave();
afx_msg void OnButtonTest();
afx_msg void OnDestroy();

afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnCancelMode();
afx_msg void OnTimer(UINT nIDEvent);
virtual void OnOK();
afx_msg void OnButton2();
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnMenuitemRgbToGray();

afx_msg void OnMenuitemOrgImag();
afx_msg void OnMenuitemBinary();
afx_msg void OnButtonScrollWnd();
afx_msg void OnMenuitemInvertY();
afx_msg void OnMenuitemInvertX();
afx_msg void OnMenuitemHisto();
afx_msg void OnMenuitemSaveGray8bit();
afx_msg void OnMenuitemSaveBinaryBmp1bit();
afx_msg void OnMenuitemGlobGrayStretch();
afx_msg void OnMenuitemHistoEqualization();

//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
double m_dbPercent;
byte m_bBrightness;
int m_nPoolWid;
int m_nPoolHei;
CBitmap m_bmp,m_newBmp;
int * m_pPoolBuff,*m_pPoolBuff1;
byte *m_pImageDateBuff,*m_pImageDateBuff1;
CDC* m_pDC;
double GetDistance(const CPoint & p1,const CPoint &p2);
int GetAmplitude(int a0,int a1,int a2,int a3,int a4);
int GetEnergyFromWaterSourece(const CPoint &ptCenter,const CPoint &pt,double radius,int energy=50);
    CBrush m_brush;
void Shocking();
void RefreshImag(void);
void AdjustContrastAndBrightness(void);//调节对比度亮度
INT m_nCount;

void LimitMaxMin(byte& val)
{
if (val>255)
{
val =255;
}
if (val<0)
{
val= 0;
}
}

void AvgChannels(int & r,int &g,int &b);
void AdjustSimpleContrastAndBrightness(void);//调节对比度亮度
void Rgb2Gray24(int typeFlag);
void Gray2Binary(byte* imageBuffer,byte threshold);
void SaveBmp(void);
    void SaveBmpSingle(void);//8bit单色位图
    void SaveBmpBinary(void);//1bit单色位图
void InvertBuffer(INT direction);
void RoateImag(CPoint & roatePos,double roateAngle);
void GetHistogram(int *Histo);
void DrawHistoGram(int *Histo);
    void Rgb2Gray8(void);
void Rgb2Gray16(void);
void Rgb2Rgb8(void);
void Rgb2Rgb16(void);
void GlobGrayStrench();//全局灰度直方图拉伸
    void HistogramEqualization(void);//直方图均衡化
    void CalculateCDF(double *p);//计算累计分布函数
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WAVEDLG_H__3AD6300B_435E_4773_8C88_DDE56BEE2A52__INCLUDED_)


////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Wave.h"
#include "WaveDlg.h"
#include<MATH.H>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CWaveDlg::CWaveDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWaveDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWaveDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_dbPercent=0.0;
m_nCount=1;
int len=6;
while (len--)
{
int a=len;
}
}

void CWaveDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWaveDlg)
DDX_Control(pDX, IDC_SLIDER2, m_slider2);
DDX_Control(pDX, IDC_SLIDER, m_sliderCtr);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CWaveDlg, CDialog)
//{{AFX_MSG_MAP(CWaveDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_STATIC_WAVE, OnStaticWave)
ON_BN_CLICKED(IDC_BUTTON_TEST, OnButtonTest)
ON_WM_DESTROY()
ON_WM_CTLCOLOR()
ON_WM_CANCELMODE()
ON_WM_TIMER()

ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
ON_WM_HSCROLL()
ON_COMMAND(ID_MENUITEM_RGB_TO_GRAY, OnMenuitemRgbToGray)
ON_COMMAND(ID_MENUITEM_ORG_IMAG, OnMenuitemOrgImag)
ON_COMMAND(ID_MENUITEM_BINARY, OnMenuitemBinary)
ON_BN_CLICKED(IDC_BUTTON_SCROLL_WND, OnButtonScrollWnd)
ON_COMMAND(ID_MENUITEM_INVERT_Y, OnMenuitemInvertY)
ON_COMMAND(ID_MENUITEM_INVERT_X, OnMenuitemInvertX)

ON_COMMAND(ID_MENUITEM_HISTO, OnMenuitemHisto)
ON_COMMAND(ID_MENUITEM_SAVE_GRAY_8BIT, OnMenuitemSaveGray8bit)
ON_COMMAND(ID_MENUITEM_SAVE_BINARY_BMP_1BIT, OnMenuitemSaveBinaryBmp1bit)
ON_COMMAND(ID_MENUITEM_GLOB_GRAY_STRETCH, OnMenuitemGlobGrayStretch)
ON_COMMAND(ID_MENUITEM_HISTO_EQUALIZATION, OnMenuitemHistoEqualization)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CWaveDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)

{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog.  The framework does this automatically
//  when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);	// Set big icon
SetIcon(m_hIcon, FALSE);	// Set small icon

// TODO: Add extra initialization here
m_bmp.LoadBitmap(IDB_BITMAP);
BITMAP bitMap;
m_bmp.GetBitmap(&bitMap);
m_nPoolWid=bitMap.bmWidth;
m_nPoolHei=bitMap.bmHeight;

    GetDlgItem(IDC_STATIC_WAVE)->SetWindowPos(NULL,0,0,m_nPoolWid,m_nPoolHei,SWP_NOMOVE);
m_pDC=GetDlgItem(IDC_STATIC_WAVE)->GetDC();
int size=m_nPoolHei*m_nPoolWid;
    m_pPoolBuff=new int[size];
m_pPoolBuff1=new int[size];
    memset(m_pPoolBuff,0,size*sizeof(int));
    memset(m_pPoolBuff1,0,size*sizeof(int));

    int ImageDateSize=size*bitMap.bmBitsPixel/8;
m_pImageDateBuff=new byte[ImageDateSize];
 
m_pImageDateBuff1=new byte[ImageDateSize];
m_bmp.GetBitmapBits(ImageDateSize,m_pImageDateBuff);


//m_newBmp.CreateCompatibleBitmap(m_pDC,m_nPoolWid,m_nPoolHei);
m_newBmp.CreateBitmap(m_nPoolWid,m_nPoolHei,1,32,m_pImageDateBuff);
//m_newBmp.CreateBitmapIndirect(&bitMap);
//m_newBmp.CreateDiscardableBitmap(m_pDC,m_nPoolWid,m_nPoolHei);
// 	//m_newBmp.SetBitmapBits(ImageDateSize,m_pImageDateBuff);
m_brush.CreateSolidBrush(RGB(255,0,0));
m_sliderCtr.SetRangeMax(100,TRUE);
m_sliderCtr.SetRangeMin(0,TRUE);

//m_sliderCtr.SetRangeMin(-100,TRUE);
m_sliderCtr.SetPos(-100);
m_sliderCtr.SetTicFreq(1);

m_slider2.SetRangeMax(255,TRUE);
m_slider2.SetRangeMin(0,TRUE);
m_slider2.SetPos(0);
m_slider2.SetTicFreq(5);
return TRUE;  // return TRUE  unless you set the focus to a control

}

void CWaveDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

void CWaveDlg::OnPaint() 
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

HCURSOR CWaveDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}


void CWaveDlg::OnStaticWave() 
{
// TODO: Add your control notification handler code here

CPoint ptCenter;
::GetCursorPos(&ptCenter);
GetDlgItem(IDC_STATIC_WAVE)->ScreenToClient(&ptCenter);
    double radius=5.0;
    if (ptCenter.x<0||ptCenter.y<0||ptCenter.x>512||ptCenter.y>512)
    {
return;
    }

CPoint ptTmp;
for (int j=0;j<m_nPoolHei;++j)
{
for (int i=0;i<m_nPoolWid;++i)
{
ptTmp.x=i;
ptTmp.y=j;
if (GetDistance(ptTmp,ptCenter)<=radius)
{
m_pPoolBuff[j*m_nPoolWid+i]=GetEnergyFromWaterSourece(ptCenter,ptTmp,radius,-500);
}
}
}
}

void CWaveDlg::OnButtonTest() 
{
 	
}

void CWaveDlg::Shocking()
{
    OnStaticWave();
int *pImageBuff=(int*)m_pImageDateBuff;
int *pImageBuff1=(int*)m_pImageDateBuff1;
for (int j=1;j<m_nPoolHei-1;++j)
{
for (int i=1;i<m_nPoolWid-1;++i)
{
   int x1=m_pPoolBuff[j*m_nPoolWid+i-1];
           int x3=m_pPoolBuff[j*m_nPoolWid+i+1];
   int y1=m_pPoolBuff[(j-1)*m_nPoolWid+i];
           int y3=m_pPoolBuff[(j+1)*m_nPoolWid+i];

           m_pPoolBuff1[j*m_nPoolWid+i]=GetAmplitude(m_pPoolBuff1[j*m_nPoolWid+i],x1,x3,y1,y3);
   m_pPoolBuff1[j*m_nPoolWid+i]-=m_pPoolBuff1[j*m_nPoolWid+i]>>7;
   int newIndexX=x3-x1+i;
           int newIndexY=y3-y1+j;
           
   if (newIndexX>m_nPoolWid)
   {
   newIndexX=m_nPoolWid;
   }
   if (newIndexX<0)
   {
   newIndexX=0;
   }

   if (newIndexY>m_nPoolHei)
   {
   newIndexY=m_nPoolHei;
   }
   if (newIndexY<0)
   {
   newIndexY=0;
   }

           pImageBuff1[j*m_nPoolWid+i]=pImageBuff[m_nPoolWid*newIndexY+newIndexX];
}
}

    int * pTmp=m_pPoolBuff;
m_pPoolBuff=m_pPoolBuff1;
    m_pPoolBuff1=pTmp;
    
RefreshImag();

}
void CWaveDlg::RefreshImag(void)
{
    m_newBmp.SetBitmapBits(m_nPoolWid*m_nPoolHei*4,m_pImageDateBuff1);	
    CDC memDC;
memDC.CreateCompatibleDC(m_pDC);
CBitmap *pOldBmp=memDC.SelectObject(&m_newBmp);
m_pDC->BitBlt(0,0,m_nPoolWid,m_nPoolHei,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
}
double CWaveDlg::GetDistance(const CPoint & p1,const CPoint &p2)
{
    return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}

int CWaveDlg::GetAmplitude(int a0,int a1,int a2,int a3,int a4)
{

 int a=((a1+a2+a3+a4)>>1)-a0;
 //a-=(a>>5);
 return a;
}
int CWaveDlg::GetEnergyFromWaterSourece(const CPoint &ptCenter,const CPoint &pt,double radius,int energy)
{
double dis=GetDistance(ptCenter,pt);
return  (int)((1-dis/radius)*energy);

}

void CWaveDlg::OnDestroy() 
{
CDialog::OnDestroy();

// TODO: Add your message handler code here
GetDlgItem(IDC_STATIC_WAVE)->ReleaseDC(m_pDC);
delete [] m_pImageDateBuff;
delete [] m_pImageDateBuff1;
delete [] m_pPoolBuff;
delete [] m_pPoolBuff1;
}
bool m_b=false;

HBRUSH CWaveDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

// TODO: Return a different brush if the default is not desired
return hbr;
}

void CWaveDlg::OnCancelMode() 
{
CDialog::OnCancelMode();

// TODO: Add your message handler code here

}

void CWaveDlg::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
Shocking();
CDialog::OnTimer(nIDEvent);
}

void CWaveDlg::OnOK() 
{
// TODO: Add extra validation here
//	CDialog::OnOK();
//SetTimer(1,40,NULL);
}

void CWaveDlg::OnButton2() 
{
// TODO: Add your control notification handler code here

}

void CWaveDlg::AvgChannels(int & r,int &g,int &b)
{
for (int j=0;j<m_nPoolHei;++j)
{
for (int i=0;i<m_nPoolWid;++i)
{
byte  b1=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
byte  g1=m_pImageDateBuff[j*m_nPoolWid*4+i*4+1];
byte  r1=m_pImageDateBuff[j*m_nPoolWid*4+i*4+2];
b+=b1;
g+=g1;
r+=r1;

}
}
int count=m_nPoolWid*m_nPoolHei;
b/=count;
g/=count;
r/=count;
}

void CWaveDlg::AdjustContrastAndBrightness(void)
{
//out=avg+(in-avg)*(1+percent);avg=128;
    int avgB=0;
    int avgG=0;
int avgR=0;
    AvgChannels(avgR,avgG,avgB);
for (int j=0;j<m_nPoolHei;++j)
for (int i=0;i<m_nPoolWid;++i)
{
           byte  b=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
   byte  g=m_pImageDateBuff[j*m_nPoolWid*4+i*4+1];
   byte  r=m_pImageDateBuff[j*m_nPoolWid*4+i*4+2];
           b=avgB+(int)((b-avgB)*(1+m_dbPercent));
   g=avgG+(int)((g-avgG)*(1+m_dbPercent));
   r=avgR+(int)((r-avgR)*(1+m_dbPercent));
   LimitMaxMin(b);
   LimitMaxMin(g);
           LimitMaxMin(r);

           m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0]=b;
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1]=g;
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2]=r;
}
}
RefreshImag();
}

void  CWaveDlg::AdjustSimpleContrastAndBrightness(void)
{
int index=0;
int index1=0;
int index2=0;
int index3=0;
for (int j=0;j<m_nPoolHei;++j)
{
for (int i=0;i<m_nPoolWid;++i)
{
index=j*(m_nPoolWid<<2)+(i<<2);
index1=index+0;
            index2=index+1;
index3=index+2;

byte  b=m_pImageDateBuff[index1];
byte  g=m_pImageDateBuff[index2];
byte  r=m_pImageDateBuff[index3];

b=b*m_dbPercent+m_bBrightness;
g=g*m_dbPercent+m_bBrightness;
r=r*m_dbPercent+m_bBrightness;
LimitMaxMin(b);
LimitMaxMin(g);
LimitMaxMin(r);

m_pImageDateBuff1[index1]=b;
m_pImageDateBuff1[index2]=g;
m_pImageDateBuff1[index3]=r;

}
}
RefreshImag();
}

void CWaveDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
// TODO: Add your message handler code here and/or call default
CSliderCtrl *pSlider=(CSliderCtrl *)pScrollBar;
if (pSlider->GetDlgCtrlID()==IDC_SLIDER)
{
        m_dbPercent=pSlider->GetPos()*0.01;

}
else if (pSlider->GetDlgCtrlID()==IDC_SLIDER2)
{
        m_bBrightness=pSlider->GetPos();
}
//OnMenuitemBinary();
AdjustSimpleContrastAndBrightness();
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CWaveDlg::Rgb2Gray24(int typeFlag)
{
   if (typeFlag==0)
   {
   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   byte  b=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0]=b;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1]=b;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2]=b;
   //byte  g=m_pImageDateBuff[j*m_nPoolWid*4+i*4+1];
       //byte  r=m_pImageDateBuff[j*m_nPoolWid*4+i*4+2];	   
   }
   }
   }

   else if(typeFlag==1)

   {
   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
   byte  g=m_pImageDateBuff[j*m_nPoolWid*4+i*4+1];
   byte  r=m_pImageDateBuff[j*m_nPoolWid*4+i*4+2];
   byte avg=(b+g+r)/3;

   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0]=avg;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1]=avg;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2]=avg;
   
   }
   }
   }

   else if (typeFlag==2)
   {
   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
   byte  g=m_pImageDateBuff[j*m_nPoolWid*4+i*4+1];
   byte  r=m_pImageDateBuff[j*m_nPoolWid*4+i*4+2];
   //byte avg=(b*11+g*59+r*30+50)/100;
   byte gray=(r+b+((USHORT)g<<1))>>2;
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0]=gray;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1]=gray;
               m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2]=gray;
   
   }
   }
   }
}

void CWaveDlg::OnMenuitemRgbToGray() 
{
// TODO: Add your command handler code here
Rgb2Gray24(2);
RefreshImag();
}

void CWaveDlg::Gray2Binary( byte* imageBuffer,byte threshold)
{
   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=imageBuffer[j*m_nPoolWid*4+i*4+0];
               if (b>=threshold)
               {
   b=255;
               }
   else
   {
                 b=0;
   }
   imageBuffer[j*m_nPoolWid*4+i*4+0]=b;
               imageBuffer[j*m_nPoolWid*4+i*4+1]=b;
               imageBuffer[j*m_nPoolWid*4+i*4+2]=b;
   
   }
   }
}

void CWaveDlg::OnMenuitemOrgImag() 
{
// TODO: Add your command handler code here
memcpy(m_pImageDateBuff1,m_pImageDateBuff,m_nPoolWid*m_nPoolHei*4);
m_newBmp.SetBitmapBits(m_nPoolWid*m_nPoolHei*4,m_pImageDateBuff);	
    CDC memDC;
memDC.CreateCompatibleDC(m_pDC);
CBitmap *pOldBmp=memDC.SelectObject(&m_newBmp);
m_pDC->BitBlt(0,0,m_nPoolWid,m_nPoolHei,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
}


void CWaveDlg::SaveBmp(void)
{
   BITMAPINFO bmpInfo;
   memset(&bmpInfo,0,sizeof(BITMAPINFO));
   BITMAPFILEHEADER bmpFileHeader;
   BITMAPINFOHEADER bmpInfoHeader;
   bmpInfoHeader.biSize=sizeof(BITMAPINFOHEADER);
   bmpInfoHeader.biBitCount=32;
   bmpInfoHeader.biWidth=m_nPoolWid;
   bmpInfoHeader.biHeight=m_nPoolHei;
   bmpInfoHeader.biPlanes=1;
   bmpInfoHeader.biClrImportant=0;

   bmpInfoHeader.biClrUsed=0;
   bmpInfoHeader.biSizeImage=0;
   bmpInfoHeader.biXPelsPerMeter=0;
   bmpInfoHeader.biYPelsPerMeter=0;
   bmpInfoHeader.biCompression=BI_RGB;


   bmpFileHeader.bfType=0x4d42;
   bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
   bmpFileHeader.bfSize=bmpFileHeader.bfOffBits+m_nPoolHei*m_nPoolWid*4;
   bmpFileHeader.bfReserved1=0;
   bmpFileHeader.bfReserved2=0;
   
   bmpInfo.bmiHeader=bmpInfoHeader;

   CFile file;
   file.Open("F:\\work\\Wave\\test.bmp",CFile::modeCreate|CFile::modeWrite);
   file.Write(&bmpFileHeader,sizeof(BITMAPFILEHEADER));
   file.Write(&bmpInfo,sizeof(BITMAPINFO));
   file.Write(m_pImageDateBuff1,m_nPoolWid*m_nPoolHei*4);

   file.Close();

}

 void CWaveDlg::SaveBmpSingle(void)
{

 byte *pBmpBuffer=new byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256];
 BITMAPINFO *pbmpInfo=(BITMAPINFO*)(pBmpBuffer);
 //memset(&bmpInfo,0,sizeof(BITMAPINFO));
     for (int k=0;k<256;k++)
     {
        pbmpInfo->bmiColors[k].rgbBlue=k;
pbmpInfo->bmiColors[k].rgbGreen=k;
pbmpInfo->bmiColors[k].rgbRed=k;
pbmpInfo->bmiColors[k].rgbReserved=0;
     }

 BITMAPFILEHEADER bmpFileHeader;
 BITMAPINFOHEADER bmpInfoHeader;
 bmpInfoHeader.biSize=sizeof(BITMAPINFOHEADER);
 bmpInfoHeader.biBitCount=8;
 bmpInfoHeader.biWidth=m_nPoolWid;
 bmpInfoHeader.biHeight=m_nPoolHei;
 bmpInfoHeader.biPlanes=1;
 bmpInfoHeader.biClrImportant=0;
 bmpInfoHeader.biClrUsed=0;
 bmpInfoHeader.biSizeImage=0;
 bmpInfoHeader.biXPelsPerMeter=0;
 bmpInfoHeader.biYPelsPerMeter=0;
 bmpInfoHeader.biCompression=BI_RGB;

 bmpFileHeader.bfType=0x4d42;
 bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256;
 bmpFileHeader.bfSize=bmpFileHeader.bfOffBits+m_nPoolHei*m_nPoolWid;
 bmpFileHeader.bfReserved1=0;
 bmpFileHeader.bfReserved2=0;

 pbmpInfo->bmiHeader=bmpInfoHeader;


 CFile file;
 file.Open("F:\\work\\Wave\\test.bmp",CFile::modeCreate|CFile::modeWrite);
 file.Write(&bmpFileHeader,sizeof(BITMAPFILEHEADER));
 file.Write(pBmpBuffer,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256);

 Rgb2Gray24(2);
     byte *pRgbIndex=new byte [m_nPoolWid*m_nPoolHei];

 for (int j=0;j<m_nPoolHei;++j)
 {
 for (int i=0;i<m_nPoolWid;++i)
 {
 
 byte  b=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0];

 pRgbIndex[j*m_nPoolWid+i]=b;
 }
   }

 file.Write(pRgbIndex,m_nPoolWid*m_nPoolHei);
 
     file.Close();
 delete[]pRgbIndex;
 delete[] pBmpBuffer;
}

void CWaveDlg::OnMenuitemBinary() 
{
// TODO: Add your command handler code here
Rgb2Gray24(2);
    Gray2Binary(m_pImageDateBuff1,m_bBrightness);
RefreshImag();
}


void CWaveDlg::InvertBuffer(INT direction)
{
if (direction==1)//x direction
{

int midWidth=m_nPoolWid/2;
int temp=0;
INT *pImageBuffer=(INT*)m_pImageDateBuff1;
for (int j=0;j<m_nPoolHei;++j)
{
for (int i=0;i<midWidth;++i)
{
temp= pImageBuffer[j*m_nPoolWid+i];
pImageBuffer[j*m_nPoolWid+i]=pImageBuffer[j*m_nPoolWid+m_nPoolWid-i-1];
pImageBuffer[j*m_nPoolWid+m_nPoolWid-i-1]  =temp; 
}
   }
}


else if (direction==2)// y direction
{
int temp=0;
int midHeight=m_nPoolHei/2;
INT *pImageBuffer=(INT*)m_pImageDateBuff1;
for (int j=0;j<midHeight;++j)
{
for (int i=0;i<m_nPoolWid;++i)
{
temp= pImageBuffer[j*m_nPoolWid+i];
pImageBuffer[j*m_nPoolWid+i]=pImageBuffer[(m_nPoolHei-1-j)*m_nPoolWid+i];
pImageBuffer[(m_nPoolHei-1-j)*m_nPoolWid+i]  =temp; 
}
   }
}

}

void CWaveDlg::OnButtonScrollWnd() 
{
// TODO: Add your control notification handler code here
//     m_nCount+=5;
// 	CRect rectClient;
// 	GetClientRect(&rectClient);
// 	::ScrollWindow(GetSafeHwnd(),0,m_nCount,&rectClient,NULL);
}

void CWaveDlg::OnMenuitemInvertY() 
{
// TODO: Add your command handler code here
InvertBuffer(2);
RefreshImag();
//SaveBmp();
}

void CWaveDlg::OnMenuitemInvertX() 
{
// TODO: Add your command handler code here
InvertBuffer(1);
RefreshImag();
}

void CWaveDlg::RoateImag(CPoint & roatePos,double roateAngle)
{

}


void CWaveDlg::GetHistogram(int *Histo)
{
   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0];
               Histo[b]++;
   }
   }

}

void CWaveDlg::OnMenuitemHisto() 
{
// TODO: Add your command handler code here
INT histo[256];
memset(histo,0,256*sizeof(INT));
Rgb2Gray24(1);
GetHistogram(histo);
DrawHistoGram(histo);
}

void CWaveDlg::DrawHistoGram(int *Histo)
{
    m_newBmp.SetBitmapBits(m_nPoolWid*m_nPoolHei*4,m_pImageDateBuff1);	
    CDC memDC;
memDC.CreateCompatibleDC(m_pDC);
CBitmap *pOldBmp=memDC.SelectObject(&m_newBmp);
    CPen pen(PS_SOLID,1,RGB(255,0,0));
CPen* pOldPen=memDC.SelectObject(&pen);

CPoint ptCord(50,m_nPoolHei-50);//坐标原点
    //画x轴
    memDC.MoveTo(ptCord.x,ptCord.y);
memDC.LineTo(m_nPoolWid,ptCord.y);

//画刻度
//memDC.MoveTo(ptCord.x,ptCord.y);
    for (int x=ptCord.x;x<ptCord.x+256;x++)
    {
       memDC.MoveTo(x,ptCord.y);
   memDC.LineTo(x,ptCord.y-Histo[x-ptCord.x]/15);
    }

//画y轴
    memDC.MoveTo(ptCord.x,ptCord.y);
memDC.LineTo(ptCord.x,0);

m_pDC->BitBlt(0,0,m_nPoolWid,m_nPoolHei,&memDC,0,0,SRCCOPY);
memDC.SelectObject(pOldBmp);
memDC.SelectObject(&pOldPen);
memDC.DeleteDC();

}
void CWaveDlg::Rgb2Gray8(void)
{


}


void CWaveDlg::Rgb2Gray16(void)
{


}
void CWaveDlg::Rgb2Rgb8(void)
{


}
void CWaveDlg::Rgb2Rgb16(void)
{


}

void CWaveDlg::OnMenuitemSaveGray8bit() 
{
// TODO: Add your command handler code here
SaveBmpSingle();
}

void CWaveDlg::SaveBmpBinary(void)
{

byte *pBmpBuffer=new byte[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*2];
BITMAPINFO *pbmpInfo=(BITMAPINFO*)(pBmpBuffer);
//memset(&bmpInfo,0,sizeof(BITMAPINFO));
for (int k=0;k<2;k++)
{
        pbmpInfo->bmiColors[k].rgbBlue=k*255;
pbmpInfo->bmiColors[k].rgbGreen=k*255;
pbmpInfo->bmiColors[k].rgbRed=k*255;
pbmpInfo->bmiColors[k].rgbReserved=0;
}

BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
bmpInfoHeader.biSize=sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biBitCount=1;
bmpInfoHeader.biWidth=m_nPoolWid;
bmpInfoHeader.biHeight=-m_nPoolHei;
bmpInfoHeader.biPlanes=1;
bmpInfoHeader.biClrImportant=0;
bmpInfoHeader.biClrUsed=0;
bmpInfoHeader.biSizeImage=0;
bmpInfoHeader.biXPelsPerMeter=0;
bmpInfoHeader.biYPelsPerMeter=0;
bmpInfoHeader.biCompression=BI_RGB;

bmpFileHeader.bfType=0x4d42;
bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*2;
bmpFileHeader.bfSize=bmpFileHeader.bfOffBits+m_nPoolHei*m_nPoolWid;
bmpFileHeader.bfReserved1=0;
bmpFileHeader.bfReserved2=0;

pbmpInfo->bmiHeader=bmpInfoHeader;

CFile file;
file.Open("F:\\work\\Wave\\test.bmp",CFile::modeCreate|CFile::modeWrite);
file.Write(&bmpFileHeader,sizeof(BITMAPFILEHEADER));
file.Write(pBmpBuffer,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*2);	
Rgb2Gray24(2);
byte shiftX=0x01;

for (int j=0;j<m_nPoolHei;++j)
{
for (int i=0;i<m_nPoolWid;++i)
{

byte  b=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0];
int k=(j*m_nPoolWid+i+1)%8;


}
  }

// 	file.Write(pRgbIndex,m_nPoolWid*m_nPoolHei/8);

file.Close();
delete[] pBmpBuffer;

}

void CWaveDlg::OnMenuitemSaveBinaryBmp1bit() 
{
// TODO: Add your command handler code here
SaveBmpBinary();
}

void CWaveDlg::OnMenuitemGlobGrayStretch() 
{
// TODO: Add your command handler code here
GlobGrayStrench();
}

void CWaveDlg::HistogramEqualization(void)
{
INT histo[256];
double pHisto[256];
memset(histo,0,256*sizeof(INT));
memset(pHisto,0,256*sizeof(double));
Rgb2Gray24(1);
GetHistogram(histo);
int count=m_nPoolHei*m_nPoolWid;
    for (int ii=0;ii<256;++ii)
    {
      pHisto[ii]=histo[ii]/(double)count;
    }
   CalculateCDF(pHisto);

   for (int j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=m_pImageDateBuff[j*m_nPoolWid*4+i*4+0];
           byte bValue=(byte)(pHisto[b]*255.0);
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0]=bValue;
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1]=bValue;
   m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2]=bValue;	   
   }
}

   GetHistogram(histo);
   DrawHistoGram(histo);
}

void CWaveDlg::CalculateCDF(double *p)
{
   for (int i=0;i<256;++i)
   {
     for (int k=0;k<=i;++k)
     {
 p[i]+=p[k];
     }
   }
}


void CWaveDlg::GlobGrayStrench()
{
INT histo[256];
memset(histo,0,256*sizeof(INT));
Rgb2Gray24(1);
   byte max=0,min=0;
   INT j;
   for ( j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  b=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0];	
   if (b>=max)
   {
   max=b;
   }
   if (b<=min)
   {
             min=b;
   }
   }
}


   byte d=max-min;

   for ( j=0;j<m_nPoolHei;++j)
   {
   for (int i=0;i<m_nPoolWid;++i)
   {
   
   byte  &b=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+0];
   byte  &g=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+1];
   byte  &r=m_pImageDateBuff1[j*m_nPoolWid*4+i*4+2];
   b=(byte)((b-min)*(255.0/d));
   g=(byte)((g-min)*(255.0/d));
   r=(byte)((r-min)*(255.0/d));
   }
}

    GetHistogram(histo);
 	DrawHistoGram(histo);
}

void CWaveDlg::OnMenuitemHistoEqualization() 
{
// TODO: Add your command handler code here
HistogramEqualization();
}

转载于:https://my.oschina.net/u/221120/blog/666332

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值