用MFC实现的一个简单的photoshop软件的制作代码

来源:互联网 发布:软件共享 编辑:程序博客网 时间:2024/05/17 20:29

// kesheView.cpp : implementation of the CKesheView class
//

#include "stdafx.h"
#include "keshe.h"

#include "kesheDoc.h"
#include "kesheView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
       bool c_bHist=false;
   int c_hist[256];   
    int c_yuan[256];
       CString filename;
/////////////////////////////////////////////////////////////////////////////
// CKesheView

IMPLEMENT_DYNCREATE(CKesheView, CView)

BEGIN_MESSAGE_MAP(CKesheView, CView)
 //{{AFX_MSG_MAP(CKesheView)
 ON_COMMAND(ID_GRAYENHANCEMENT_IMAGE, OnGrayenhancementImage)
 ON_COMMAND(ID_OPEN_IMAGE, OnOpenImage)
 ON_COMMAND(ID_ZFTDISPLAY_IMAGE, OnZftdisplayImage)
 ON_COMMAND(ID_ZFTEQUALIZATION_IMAGE, OnZftequalizationImage)
 ON_COMMAND(ID_BASRELIEF_IMAGE, OnBasreliefImage)
 ON_COMMAND(ID_ATOMIZATION_IMAGE, OnAtomizationImage)
 ON_COMMAND(ID_RECOVER_IMAGE, OnRecoverImage)
 ON_COMMAND(ID_DIVISION_IMAGE, OnDivisionImage)
 //}}AFX_MSG_MAP
 // Standard printing commands
 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CKesheView construction/destruction

CKesheView::CKesheView()
{
 // TODO: add construction code here

}

CKesheView::~CKesheView()
{
}

BOOL CKesheView::PreCreateWindow(CREATESTRUCT& cs)
{
 // TODO: Modify the Window class or styles here by modifying
 //  the CREATESTRUCT cs

 return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CKesheView drawing

void CKesheView::OnDraw(CDC* pDC)
{
 CKesheDoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 // TODO: add draw code for native data here
   if(c_dib.m_bLoaded==true)  //判断是否加载图像
 {
    //获取图像宽和高
   int nw=c_dib.GetDIBWidth();
   int nh=c_dib.GetDIBHeight();
  // 显示图像(具体的参数见CDIB类的该函数说明)
   c_dib.ShowDIB(pDC,10,10,nw,nh,c_dib.m_pDIBData,c_dib.m_pBMI);
   c_dib.ShowDIB(pDC,400,10,nw,nh,c_dib.m_pDumpDIBData,c_dib.m_pBMI);
}
   if(c_bHist==true)
  {
   CString str;
   int nh=c_dib.GetDIBHeight();
   int i;
   // 画坐标轴
   // 绘制坐标轴(原始的)
   
   pDC->MoveTo(410,nh+20);  //是直方图的左上角坐标
   // 垂直轴
   pDC->LineTo(410,nh+200);//是直方图的左下角坐标
   // 水平轴
   pDC->LineTo(710,nh+200);//是直方图的右下角坐标
   // 写X轴刻度值
   str.Format("0");
   pDC->TextOut(410, nh+200+10, str);
   str.Format("50");
   pDC->TextOut(460, nh+200+10, str);
   str.Format("100");
   pDC->TextOut(510, nh+200+10, str);
   str.Format("150");
   pDC->TextOut(560, nh+200+10, str);
   str.Format("200");
   pDC->TextOut(610, nh+200+10, str);
   str.Format("250");
   pDC->TextOut(660, nh+200+10, str);

   pDC->MoveTo(10,nh+20);  //是直方图的左上角坐标
   // 垂直轴
   pDC->LineTo(10,nh+200);//是直方图的左下角坐标
   // 水平轴
   pDC->LineTo(310,nh+200);//是直方图的右下角坐标
   // 写X轴刻度值
   str.Format("0");
   pDC->TextOut(10, nh+200+10, str);
   str.Format("50");
   pDC->TextOut(60, nh+200+10, str);
   str.Format("100");
   pDC->TextOut(110, nh+200+10, str);
   str.Format("150");
   pDC->TextOut(160, nh+200+10, str);
   str.Format("200");
   pDC->TextOut(210, nh+200+10, str);
   str.Format("250");
   pDC->TextOut(265, nh+200+10, str);
   // 绘制X轴刻度
   for ( i = 0; i < 256; i += 25)
    {
    
     pDC->MoveTo(i + 10, nh+200-2);
     pDC->LineTo(i + 10, nh+200+2);
    }
   // 绘制X轴箭头
   pDC->MoveTo(705,nh+200-5);
   pDC->LineTo(710,nh+200);
   pDC->LineTo(705,nh+200+5);
   // 绘制y轴箭头
   pDC->MoveTo(410,nh+20);
   pDC->LineTo(405,nh+20+5);
   pDC->MoveTo(410,nh+20);
   pDC->LineTo(415,nh+20+5);

   // 绘制X轴箭头
   pDC->MoveTo(305,nh+200-5);
   pDC->LineTo(310,nh+200);
   pDC->LineTo(305,nh+200+5);
   // 绘制y轴箭头
   pDC->MoveTo(10,nh+20);
   pDC->LineTo(5,nh+20+5);
   pDC->MoveTo(10,nh+20);
   pDC->LineTo(15,nh+20+5);
   int max=0;
   for(i=0;i<256;i++)
    if(c_yuan[i]>max)
     max=c_yuan[i];
   for(i=0;i<256;i++)
   {
    pDC->MoveTo(410+i,nh+200);
    pDC->LineTo(410+i,nh+200-(c_yuan[i]*180/max));
   }
      max=0;
   for(i=0;i<256;i++)
    if(c_hist[i]>max)
     max=c_hist[i];
   for(i=0;i<256;i++)
   {
    pDC->MoveTo(10+i,nh+200);
    pDC->LineTo(10+i,nh+200-(c_hist[i]*180/max));
   }
  }

}

/////////////////////////////////////////////////////////////////////////////
// CKesheView printing

BOOL CKesheView::OnPreparePrinting(CPrintInfo* pInfo)
{
 // default preparation
 return DoPreparePrinting(pInfo);
}

void CKesheView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add extra initialization before printing
}

void CKesheView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
 // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CKesheView diagnostics

#ifdef _DEBUG
void CKesheView::AssertValid() const
{
 CView::AssertValid();
}

void CKesheView::Dump(CDumpContext& dc) const
{
 CView::Dump(dc);
}

CKesheDoc* CKesheView::GetDocument() // non-debug version is inline
{
 ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CKesheDoc)));
 return (CKesheDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CKesheView message handlers

void CKesheView::OnGrayenhancementImage()
{
 // TODO: Add your command handler code here
 //功能:对图像进行对比度拉伸

 //////////////////////////
 //判断图像是否打开,没打开,则弹出提示框并退出函数
 if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }

    //获取图像宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
 int i,j;
   

 //对每一个象素进行灰度增加处理
 for(j=0;j<nh;j++)
  for(i=0;i<nw;i++)
  {
   //对图像的第j行、第i列的象素的灰度信息进行判断,修改
   int gray=c_dib.m_pdata[j*nw+i];
   if(c_dib.m_pdata[j*nw+i]>=0 && c_dib.m_pdata[j*nw+i]<50)
    c_dib.m_pdata[j*nw+i]=0.4*gray;
           else if(c_dib.m_pdata[j*nw+i]>=50 && c_dib.m_pdata[j*nw+i]<150)
     {
      c_dib.m_pdata[j*nw+i]=1.8*(gray-50)+20;
      c_dib.m_pdata[j*nw+i]=(c_dib.m_pdata[j*nw+i]>250)? 250:c_dib.m_pdata[j*nw+i];
     }
     else
     {
        c_dib.m_pdata[j*nw+i]=0.5*(gray-150)+200;
     }

  }

//将修改的m_pdata的数据赋值给m_pDIBData,以显示修改的结果
 c_dib.UpdateData();
 //刷新屏幕
 Invalidate();

 
}

void CKesheView::OnOpenImage()
{
 // TODO: Add your command handler code here
    static char szFilter[]="BMP文件(*.bmp)|*.bmp||";  //定义过滤文件的类型
     CFileDialog dlg(TRUE,"bmp",NULL,
  OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);//定义文件对话框对象
  
    int ret=dlg.DoModal();  //运行打开文件对方框
    if(ret==IDOK)
    {  
  filename=dlg.GetFileName();     //获取所选择图像的路径
   c_dib.LoadFromFile(filename);   //加载图像
   if(!c_dib.m_bLoaded)            //判断是否加载图像成功
   {
   AfxMessageBox("图像打不开");
   return;
   }
  }
        c_bHist=false;
    int i,j;
    int nw=c_dib.GetDIBWidth();
    int nh=c_dib.GetDIBHeight();
     for(j=0;j<nh;j++)
     for(i=0;i<nw;i++)
     {
      c_yuan[c_dib.m_pdata[j*nw+i]]++;
     }
Invalidate(1); //刷新屏幕

 
}

void CKesheView::OnZftdisplayImage()
{
 // TODO: Add your command handler code here
 //实现直方图的显示
  if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }
     //获取图像的宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
 int i,j;
 for(j=0;j<nh;j++)
  for(i=0;i<nw;i++)
  {
  
  c_hist[c_dib.m_pdata[j*nw+i]]++;
  }                                    

  
   c_bHist=true;
   c_dib.UpdateData();//将修改的m_pdata的数据赋值给m_pDIBData,显示修改的结果
   Invalidate();//刷新屏幕
 
}

void CKesheView::OnZftequalizationImage()
{
 // TODO: Add your command handler code here
 //实现图像的直方图均衡化
 if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }
     //获取图像的宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
 int i,j,k,max=0,min=0;
   int n[256]={0};//n[i]灰度值为i的像素的个数
   float p[256]={0.0};//p[i]灰度为i的像素个数的归一化
   float c[256]={0.0};//c[i]灰度为i的像素个数的累积归一化
  for(i=0;i<nh;i++)//统计直方图每个灰度级出现的次数
   {
   for(j=0;j<nw;j++)
{
    k=c_dib.m_pdata[i*nw+j];
    n[k]++;}
  }
for(i=0;i<256;i++)//归一化直方图
{
 p[i]=(float)n[i]/(nw*nh);//强制类型转换
}
for(i=0;i<256;i++)//累积归一化直方图
  for(j=0;j<=i;j++)
{
   c[i]+=p[j];
  }
for(i=0;i<nh;i++)//找出像素的最大值和最小值
{
 for(j=0;j<nw;j++)
{
  if(max<=c_dib.m_pdata[i*nw+j]) max=c_dib.m_pdata[i*nw+j];
  if(min>=c_dib.m_pdata[i*nw+j]) min=c_dib.m_pdata[i*nw+j];
 }
}
for(i=0;i<nh;i++)//直方图均衡化
{
 for(j=0;j<nw;j++)
{
  c_dib.m_pdata[i*nw+j]=c[c_dib.m_pdata[i*nw+j]]*(max-min)+min+0.5;//c[c_dib.m_pdata[i*nw+j]]相当于求该灰度值的累积分布函数
 }
}
c_dib.UpdateData();//将修改的m_pdata的数据赋值给m_pDIBData,显示修改的结果
Invalidate();//刷新屏幕
 
}

void CKesheView::OnBasreliefImage()
{
 // TODO: Add your command handler code here
 //实现图像的浮雕化处理
    if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }
     //获取图像的宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
    int i,j,temp;
    for(i=0;i<nh;i++)
      for(j=(nw-1);j>=0;j--)
   {
         temp=c_dib.m_pdata[i*nw+j]-c_dib.m_pdata[(i+1)*nw+j-1]+128;
   if(temp>255)  temp=255;
   if(temp<0)    temp=0;
          c_dib.m_pdata[i*nw+j]=temp;
   }
        c_dib.UpdateData();//将修改的m_pdata的数据赋值给m_pDIBData,显示修改的结果
  Invalidate();//刷新屏幕

}

void CKesheView::OnAtomizationImage()
{
 // TODO: Add your command handler code here
 //实现图像的雾化处理
    if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }
     //获取图像的宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
    int i,j,k,dat;  //i表示列,j表行
  byte *ptemp=(byte *)new byte[nw*nh];//新建一个与原图像同样大小的byte类型的空间,并用ptemp指针返回空间的地址  
  memset(ptemp,0,nw*nh);//将所开辟的空间的所有灰度值置零    
   for(j=0;j<nh;j++)  
     for(i=0;i<nw;i++)  
  {   
   k=rand()%8;//取任意的随机值   
   dat=j*nw+i+k;   
   if(dat>=nw*nh)    
              dat=nw*nh-1;
      ptemp[j*nw+i]=c_dib.m_pdata[dat];
 
  }
 memcpy(c_dib.m_pdata,ptemp,nw*nh);//用新建空间的灰度值覆盖原来图像的灰度值 
  c_dib.UpdateData(); 
  Invalidate();   //刷新屏幕

}

void CKesheView::OnRecoverImage()
{
 // TODO: Add your command handler code here
       c_dib.LoadFromFile(filename);
  Invalidate();
 
}

void CKesheView::OnDivisionImage()
{
 // TODO: Add your command handler code here
    if(!c_dib.m_bLoaded) 
 {
  AfxMessageBox("图像还打开,请先打开图像!");
  return;
 }
     //获取图像的宽和高
 int nw=c_dib.GetDIBWidth();
 int nh=c_dib.GetDIBHeight();
 int i,j,temp;
    for(i=0;i<nh;i++)
      for(j=0;j<nw;j++)
   {
        if(c_dib.m_pdata[i*nw+j]>125)
    c_dib.m_pdata[i*nw+j]=255;
  else
    c_dib.m_pdata[i*nw+j]=0;
   }
        c_dib.UpdateData();//将修改的m_pdata的数据赋值给m_pDIBData,显示修改的结果
  Invalidate();//刷新屏幕
}

0 0
原创粉丝点击