以前写一些VC6.0的数字图像处理程序,大多是用对话框写的。主要是因为对话框就那么两个类:App类和Dlg类,所以理解也比较简单。但是,最近,听到有人这么讲文档视图类才是MFC的核心。所以,也想尝试一下。这两天做了点简单的尝试,特此总结一下。
1、写一个DIB类,因为在单文档或多文档下,如果不写一个DIB类,那么你做处理就比较麻烦了。因为我们经常要将这个DIB类的对象来共享,比如一般的DIB类的对象都是放到Doc类中。那么我们经常要在View类和MainFrame类中引用到Doc类的Dib类的实例。如果是多个Doc类和View类,这种数据的共享就显得更加重要了。
2、在DIB类中要有一个获得图像像素数据的指针的函数和一个能够设置DIB类的像素数据的指针。因为,在MainFrame类中我们需要获得Doc类的一个DIB类的对象之后,可以获得指向该对象的像素数据的指针,因为我们要对其中的像素数据进行操作。另外,我们要将操作之后的像素数据拷贝进DIB类的对象的像素数据中。
3、DIB类中还需要有获得操作像素数据中要用到的函数:获得图像高度、获得图像宽度、获得图像位数、获得图像每行像素所占的字节数。
4、DIB类中当然还需要有读入和写出图像的函数。
5、由于菜单的响应函数都是在MainFrame类中,所以,我们需要在MainFrame类中获得Doc类和View类的指针。获得Doc类的指针主要是利用其中的DIB类的对象;获得View类的指针主要是更新显示处理后的图像效果。所以在MainFrame类的cpp文件的包含文件中要包含Doc类和View类的h文件。获得方法是调用MainFrame类的GetActiveDoc()和GetActiveView()函数。
好了,下面说说主要的程序:
DIB类的头文件:
//Dib.h: interface for the CDib class.
//
//////////////////////////////////////////////////////////////////////
#if!defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_)
#defineAFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_
#if_MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDib
{
public:
CDib();//构造函数
virtual ~CDib();//析构函数
private:
BITMAPFILEHEADER *m_pBmfh;//保存位图文件头
BYTE *m_pBmInfo;//保存位图信息头+调色板(用于显示位图)
BYTE *m_pPixel;//保存位图像素数据
BITMAPINFOHEADER*m_pBmih;//保存位图信息头
public:
BOOL m_bRead;//标志是否调用了Read函数
public:
int Read(CString filename);//读入位图
void Draw(CDC *pDC);//显示位图
int Write(CStringfilename);//写出位图
public:
DWORD GetWidth() const;//获得位图宽度
DWORD GetHeight()const;//获得位图高度
WORD GetBitCount()const;//获得位图位数
DWORD GetLineBytes()const;//获得位图每行像素所占字节数
BYTE* GetPixelPointer()const;//获得指向位图像素数据的指针
void SetPixelMatrix(BYTE*newPixel);//设置位图的像素矩阵
};
#endif //!defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_)
DIB类的cpp文件:
//Dib.cpp: implementation of the CDib class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "VampireImage.h"
#include "Dib.h"//包含DIB类的头文件
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDib::CDib()
{
m_pBmfh=new BITMAPFILEHEADER;
m_pBmih=new BITMAPINFOHEADER;
m_pBmInfo=NULL;
m_pPixel=NULL;
m_bRead=FALSE;
}
CDib::~CDib()
{
if(m_pBmfh)
{
delete m_pBmfh;
m_pBmfh=NULL;
}
if(m_pBmih)
{
delete m_pBmih;
m_pBmih=NULL;
}
if(m_pBmInfo)
{
delete[] m_pBmInfo;
m_pBmInfo=NULL;
}
if(m_pPixel)
{
delete[] m_pPixel;
m_pPixel=NULL;
}
}
//////////////////////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////////////////////
intCDib::Read(CString filename)
{
CFile dib;
if(!dib.Open(filename,CFile::modeRead))
{
return -1;
}
if(dib.Read(m_pBmfh,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER))
{//读取位图文件头
dib.Close();
return -1;
}
m_pBmInfo=newBYTE[m_pBmfh->bfOffBits-14];//为信息头+调色板分配空间
if(!m_pBmInfo)
{
dib.Close();
return -1;
}
if(dib.Read(m_pBmInfo,m_pBmfh->bfOffBits-14)!=(m_pBmfh->bfOffBits-14))
{//读取位图信息头+调色板(如果有)
delete[] m_pBmInfo;
m_pBmInfo=NULL;
dib.Close();
return -1;
}
memcpy(m_pBmih,m_pBmInfo,sizeof(BITMAPINFOHEADER));//拷贝40字节到位图信息头中
WORDbitCount=m_pBmih->biBitCount;
DWORDwidth=m_pBmih->biWidth;
DWORDheight=m_pBmih->biHeight;
DWORDlineBytes=(width*bitCount+31)/32*4;
m_pPixel=newBYTE[height*lineBytes*sizeof(BYTE)];//为位图像素矩阵分配空间
if(!m_pPixel)
{
dib.Close();
return -1;
}
if(dib.Read(m_pPixel,height*lineBytes*sizeof(BYTE))!=(height*lineBytes*sizeof(BYTE)))
{//读取位图像素矩阵
dib.Close();
delete[] m_pBmInfo;
m_pBmInfo=NULL;
delete[] m_pPixel;
m_pPixel=NULL;
return -1;
}
dib.Close();
m_bRead=TRUE;//标志已经使用过Read函数
return 0;
}
intCDib::Write(CString filename)
{
CFile dib;
if(!dib.Open(filename,CFile::modeWrite |CFile::modeCreate | CFile::typeBinary))
{
return -1;
}
dib.Write(m_pBmfh,sizeof(BITMAPFILEHEADER));//写入位图文件头
dib.Write(m_pBmInfo,m_pBmfh->bfOffBits-14);//写入位图信息头+调色板(如果有)
dib.Write(m_pPixel,GetHeight()*GetLineBytes()*sizeof(BYTE));//写入位图像素矩阵
dib.Close();
return 0;
}
void CDib::Draw(CDC *pDC)
{
DWORD width=GetWidth();
DWORD height=GetHeight();
StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,height,m_pPixel,(BITMAPINFO*)m_pBmInfo,DIB_RGB_COLORS,SRCCOPY);//用StretchDIBits显示位图
}
//////////////////////////////////////////////////////////////////////
// Get/Set Functions
//////////////////////////////////////////////////////////////////////
WORD CDib::GetBitCount() const
{
return m_pBmih->biBitCount;
}
DWORD CDib::GetWidth() const
{
return m_pBmih->biWidth;
}
DWORD CDib::GetHeight() const
{
return m_pBmih->biHeight;
}
DWORD CDib::GetLineBytes() const
{
return (GetWidth()*GetBitCount()+31)/32*4;
}
BYTE* CDib::GetPixelPointer() const
{
return m_pPixel;
}
void CDib::SetPixelMatrix(BYTE *newPixel)
{
delete[] m_pPixel;//删除原来的像素矩阵
m_pPixel=NULL;
m_pPixel=newBYTE[GetHeight()*GetLineBytes()];//为新的像素矩阵分配空间
if(!m_pPixel)
{
return;
}
memcpy(m_pPixel,newPixel,GetHeight()*GetLineBytes());//将心的像素矩阵拷贝到DIB类中
}
View类中的OnDraw函数:
void CVampireImageView::OnDraw(CDC* pDC)
{
CVampireImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(pDoc->GetDibInstance()->m_bRead==TRUE)
{//如果已经读入图片,则调用DIB类的对象的Draw函数来显示位图
pDoc->GetDibInstance()->Draw(pDC);
}
}
Doc类中的获得DIB类的对象的指针的函数:
CDib* CVampireImageDoc::GetDibInstance()
{
return m_pDib;
}
Doc类中的打开和保存菜单的函数:
BOOL CVampireImageDoc::OnOpenDocument(LPCTSTRlpszPathName)
{
if(!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation codehere
m_pDib->Read(lpszPathName);
return TRUE;
}
CDib* CVampireImageDoc::GetDibInstance()
{
return m_pDib;
}
BOOL CVampireImageDoc::OnSaveDocument(LPCTSTRlpszPathName)
{
// TODO: Add your specialized code here and/orcall the base class
CFileDialogsfd(false,"*.bmp",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"BMPFiles(*.bmp)|*.bmp||");
if(sfd.DoModal()!=IDOK)
{
return FALSE;
}
if((m_pDib->Write(sfd.GetPathName()))==-1)
{
AfxMessageBox("保存失败");
return FALSE;
}
return TRUE;
;
}
MainFrame类中灰度图菜单的响应函数:
void CMainFrame::OnGrayimage()
{
// TODO: Add your command handler code here
CVampireImageDoc*pDoc=(CVampireImageDoc*)this->GetActiveDocument();//获得当前的Doc类的指针
DWORDwidth=(pDoc->GetDibInstance())->GetWidth();//获得DIB对象的宽度
DWORDheight=(pDoc->GetDibInstance())->GetHeight();//获得DIB对象的高度
WORDbitCount=(pDoc->GetDibInstance())->GetBitCount();//获得DIB对象的位数
DWORDlineBytes=(pDoc->GetDibInstance())->GetLineBytes();//获得DIB对象的每行所占字节数
BYTE*dib=(pDoc->GetDibInstance())->GetPixelPointer();//得到DIB对象的像素数据的指针
BYTE *newDib=newBYTE[height*lineBytes];//新建一块内存
if(!newDib)
{
return;
}
memcpy(newDib,dib,height*lineBytes);//将DIB对象的像素数据拷贝至新建的内存
if(bitCount==8)//如果位图是8位
{
AfxMessageBox("已经是8位的灰度图了,没有必要再转换。");
delete[] newDib;
newDib=NULL;
return;
}
else if(bitCount==24)//如果位图是24位
{
for(DWORDi=0;i<height;i++)
{
for(DWORDj=0,n=0;j<width*3;j++,n++)
{
BYTEb=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTEg=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTEr=*(newDib+lineBytes*(height-1-i)+j);
doubleavg=(b+g+r)/3.0;
if(avg<=0)avg=0;
if(avg>=255)avg=255;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
}
}
}
else
{
AfxMessageBox("暂时只支持8或24位位图.");
delete[] newDib;
newDib=NULL;
return;
}
pDoc->GetDibInstance()->SetPixelMatrix(newDib);//设置计算后的像素矩阵代替原来DIB对象的像素矩阵
delete[] newDib;//删除分配的内存空间
newDib=NULL;
CVampireImageView*pView=(CVampireImageView*)this->GetActiveView();//获得当前View类的指针
pView->OnDraw(pView->GetDC());//使当前View类重画
}
运行效果如图:略
用VC6.0单文档进行数字图像处理。但是,每次都是在一个View类的派生视图类上进行显示,看不出和源图像的对比性,为此,我们可以用CSplitterWnd类来讲单文档窗口分割为两个视图类,这样,左边的视图类显示源图像,右边的视图类就可以显示处理后的图像。这样对比性就一目了然了。也就是常说的用CSplitterWnd类来实现单文档多视图(一文档多视图)的效果。为此,我们还需要对我们的DIB类做一定的修改。
1、DIB类中需要两个保存像素数据的内存,一个存放源图像的像素数据,一个存放处理后图像的像素数据。并且要为它们各自设置一个取得指针和设置其像素数据的方法。
2、在DIB类的Read函数中,同时将源图像的像素数据复制到两个保存像素数据的内存,并在析构函数中对这两块内存进行删除。
3、两个视图类之间的切换。采用的CSplitterWnd类的对象的ActiveNext函数来实现,而且在两个视图类的OnDraw函数中绘制位图。
4、DIB类需要两个画图函数,以便在不同的视图类上画图。
主要程序如下:(下载全部源程序:http://download.csdn.net/source/1217835)
我新添加的派生于CView类的派生类名为CDstView类。
void CDstView::OnDraw(CDC*pDC)
{
// TODO: add draw codehere
CMainFrame*pMain=(CMainFrame*)AfxGetApp()->m_pMainWnd;
CVampireImageDoc*pDoc=(CVampireImageDoc*)pMain->GetActiveDocument();
if(pDoc->GetDibInstance()->m_bRead==TRUE)
{//如果已经读入位图,则显示位图
pDoc->GetDibInstance()->Draw(pDC);
}
}
CVampireImageDoc*CDstView::GetDocument()
{//重载GetDocument方法
return(CVampireImageDoc*)m_pDocument;
}
新的DIB类的全部源程序:
// Dib.h: interface for the CDibclass.
//
//////////////////////////////////////////////////////////////////////
#if!defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_)
#defineAFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_
#if _MSC_VER >1000
#pragma once
#endif // _MSC_VER >1000
class CDib
{
public:
CDib();//构造函数
virtual ~CDib();//析构函数
private:
BITMAPFILEHEADER*m_pBmfh;
BYTE *m_pBmInfo;
BYTE*m_pPixel;
BITMAPINFOHEADER*m_pBmih;
BYTE*m_pPrev;
public:
BOOLm_bRead;
public:
int Read(CStringfilename);
void Draw(CDC*pDC);
void DrawPrev(CDC*pDC);//显示源图像
int Write(CStringfilename);
public:
DWORD GetWidth()const;
DWORD GetHeight()const;
WORD GetBitCount()const;
DWORD GetLineBytes()const;
BYTE*GetPixelPointer() const;//得到目的图像的像素矩阵的指针
voidSetPixelMatrix(BYTE *newPixel);//设置目的图像的像素矩阵的指针
BYTE*GetPrevPixelPointer() const;//得到源图像的像素矩阵的指针
void SetPrevPixelMatrix(BYTE*newPixel);//设置源图像的像素矩阵的指针
};
#endif //!defined(AFX_DIB_H__1065C5DA_1C47_464F_A225_AAF8D2F15064__INCLUDED_)
// Dib.cpp: implementation of the CDibclass.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "VampireImage.h"
#include "Dib.h"
#ifdef _DEBUG
#undef THIS_FILE
static charTHIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDib::CDib()
{
m_pBmfh=newBITMAPFILEHEADER;
m_pBmih=newBITMAPINFOHEADER;
m_pBmInfo=NULL;
m_pPixel=NULL;
m_pPrev=NULL;
m_bRead=FALSE;
}
CDib::~CDib()
{
if(m_pBmfh)
{
deletem_pBmfh;
m_pBmfh=NULL;
}
if(m_pBmih)
{
deletem_pBmih;
m_pBmih=NULL;
}
if(m_pBmInfo)
{
delete[]m_pBmInfo;
m_pBmInfo=NULL;
}
if(m_pPixel)
{
delete[]m_pPixel;
m_pPixel=NULL;
}
if(m_pPrev)
{
delete[]m_pPrev;
m_pPrev=NULL;
}
}
//////////////////////////////////////////////////////////////////////
// Methods
//////////////////////////////////////////////////////////////////////
int CDib::Read(CStringfilename)
{//读取位图
CFiledib;
if(!dib.Open(filename,CFile::modeRead))
{
return-1;
}
if(dib.Read(m_pBmfh,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER))
{
dib.Close();
return-1;
}
m_pBmInfo=newBYTE[m_pBmfh->bfOffBits-14];
if(!m_pBmInfo)
{
dib.Close();
return-1;
}
if(dib.Read(m_pBmInfo,m_pBmfh->bfOffBits-14)!=(m_pBmfh->bfOffBits-14))
{
delete[]m_pBmInfo;
m_pBmInfo=NULL;
dib.Close();
return-1;
}
memcpy(m_pBmih,m_pBmInfo,sizeof(BITMAPINFOHEADER));
WORDbitCount=m_pBmih->biBitCount;
DWORDwidth=m_pBmih->biWidth;
DWORDheight=m_pBmih->biHeight;
DWORDlineBytes=(width*bitCount+31)/32*4;
m_pPixel=newBYTE[height*lineBytes*sizeof(BYTE)];
if(!m_pPixel)
{
dib.Close();
return-1;
}
m_pPrev=newBYTE[height*lineBytes*sizeof(BYTE)];
if(!m_pPrev)
{
dib.Close();
return-1;
}
if(dib.Read(m_pPixel,height*lineBytes*sizeof(BYTE))!=(height*lineBytes*sizeof(BYTE)))
{
dib.Close();
delete[]m_pBmInfo;
m_pBmInfo=NULL;
delete[]m_pPixel;
m_pPixel=NULL;
return-1;
}
dib.Close();
m_bRead=TRUE;
memcpy(m_pPrev,m_pPixel,height*lineBytes*sizeof(BYTE));
return0;
}
int CDib::Write(CStringfilename)
{//写出位图
CFiledib;
if(!dib.Open(filename,CFile::modeWrite| CFile::modeCreate | CFile::typeBinary))
{
return-1;
}
dib.Write(m_pBmfh,sizeof(BITMAPFILEHEADER));
dib.Write(m_pBmInfo,m_pBmfh->bfOffBits-14);
dib.Write(m_pPixel,GetHeight()*GetLineBytes()*sizeof(BYTE));
dib.Close();
return0;
}
void CDib::Draw(CDC *pDC)
{//显示目的图像
DWORDwidth=GetWidth();
DWORDheight=GetHeight();
StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,height,m_pPixel,(BITMAPINFO*)m_pBmInfo,DIB_RGB_COLORS,SRCCOPY);
}
void CDib::DrawPrev(CDC*pDC)
{//显示源图像
DWORDwidth=GetWidth();
DWORDheight=GetHeight();
StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,height,m_pPrev,(BITMAPINFO*)m_pBmInfo,DIB_RGB_COLORS,SRCCOPY);
}
//////////////////////////////////////////////////////////////////////
// Get/Set Functions
//////////////////////////////////////////////////////////////////////
WORD CDib::GetBitCount()const
{
returnm_pBmih->biBitCount;
}
DWORD CDib::GetWidth()const
{
returnm_pBmih->biWidth;
}
DWORD CDib::GetHeight()const
{
returnm_pBmih->biHeight;
}
DWORD CDib::GetLineBytes()const
{
return(GetWidth()*GetBitCount()+31)/32*4;
}
BYTE* CDib::GetPixelPointer()const
{
returnm_pPixel;
}
void CDib::SetPixelMatrix(BYTE*newPixel)
{
delete[]m_pPixel;
m_pPixel=NULL;
m_pPixel=newBYTE[GetHeight()*GetLineBytes()];
if(!m_pPixel)
{
return;
}
memcpy(m_pPixel,newPixel,GetHeight()*GetLineBytes());
}
BYTE* CDib::GetPrevPixelPointer()const
{
returnm_pPrev;
}
void CDib::SetPrevPixelMatrix(BYTE*newPixel)
{
delete[]m_pPrev;
m_pPrev=NULL;
m_pPrev=newBYTE[GetHeight()*GetLineBytes()];
if(!m_pPrev)
{
return;
}
memcpy(m_pPrev,newPixel,GetHeight()*GetLineBytes());
}
在MainFrame类中添加如下成员变量:
protected: // control barembedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CSplitterWndm_wndSplitter;
在MainFrame类的OnCreateClient函数中的程序:
BOOLCMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*pContext)
{
// TODO: Add yourspecialized code here and/or call the base class
CRectrc;
GetClientRect(&rc);
m_wndSplitter.CreateStatic(this,1,2);//分割窗口
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CVampireImageView),CSize(rc.Width()/2-16,rc.Height()/2-16),pContext);
m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CDstView),CSize(rc.Width()/2-16,rc.Height()/2-16),pContext);
returnTRUE;//必须返回TRUE,否则不能显示分割后的窗口
}
转化为灰度的程序:
voidCMainFrame::OnGrayimage()
{
// TODO: Add yourcommand handler code here
CVampireImageDoc*pDoc=(CVampireImageDoc*)this->GetActiveDocument();
if(pDoc->GetDibInstance()->m_bRead==FALSE)
{//如果还没有读入位图,则返回
return;
}
DWORDwidth=(pDoc->GetDibInstance())->GetWidth();
DWORDheight=(pDoc->GetDibInstance())->GetHeight();
WORDbitCount=(pDoc->GetDibInstance())->GetBitCount();
DWORDlineBytes=(pDoc->GetDibInstance())->GetLineBytes();
BYTE*dib=(pDoc->GetDibInstance())->GetPrevPixelPointer();//得到源图像的像素矩阵的指针
BYTE *newDib=newBYTE[height*lineBytes];
if(!newDib)
{
return;
}
memcpy(newDib,dib,height*lineBytes);//拷贝至新分配的内存
if(bitCount==8)
{
AfxMessageBox("已经是8位的灰度图了,没有必要再转换。");
delete[]newDib;
newDib=NULL;
return;
}
elseif(bitCount==24)
{
for(DWORDi=0;i<height;i++)
{
for(DWORD j=0,n=0;j<width*3;j++,n++)
{
BYTE b=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTE g=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTE r=*(newDib+lineBytes*(height-1-i)+j);
double avg=(b+g+r)/3.0;
if(avg<=0) avg=0;
if(avg>=255) avg=255;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
}
}
}
else
{
AfxMessageBox("暂时只支持8或24位位图.");
delete[]newDib;
newDib=NULL;
return;
}
pDoc->GetDibInstance()->SetPixelMatrix(newDib);//设置目的图像的像素矩阵
delete[]newDib;
newDib=NULL;
m_wndSplitter.ActivateNext();//激活CDstView的CSplitterWnd的窗口
CDstView*pView=(CDstView*)this->GetActiveView();//获得CDstView的指针
pView->OnDraw(pView->GetDC());//将目的图像画到CDstView的CSplitterWnd窗口中
m_wndSplitter.ActivateNext();//还原CVampireImageView为激活的窗口
}
转化为二值化的程序:
voidCMainFrame::OnBinaryimage()
{
// TODO: Add yourcommand handler code here
CVampireImageDoc*pDoc=(CVampireImageDoc*)this->GetActiveDocument();
if(pDoc->GetDibInstance()->m_bRead==FALSE)
{
return;
}
DWORDwidth=(pDoc->GetDibInstance())->GetWidth();
DWORDheight=(pDoc->GetDibInstance())->GetHeight();
WORDbitCount=(pDoc->GetDibInstance())->GetBitCount();
DWORDlineBytes=(pDoc->GetDibInstance())->GetLineBytes();
BYTE*dib=(pDoc->GetDibInstance())->GetPrevPixelPointer();
BYTE *newDib=newBYTE[height*lineBytes];
if(!newDib)
{
return;
}
memcpy(newDib,dib,height*lineBytes);
if(bitCount==8)
{
for(DWORDi=0;i<height;i++)
{
for(DWORD j=0;j<width;j++)
{
BYTE g=*(newDib+lineBytes*(height-1-i)+j);
if(g>128)
{
*(newDib+lineBytes*(height-1-i)+j)=255;
}
else
{
*(newDib+lineBytes*(height-1-i)+j)=0;
}
}
}
}
elseif(bitCount==24)
{
for(DWORDi=0;i<height;i++)
{
for(DWORD j=0,n=0;j<width*3;j++,n++)
{
BYTE b=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTE g=*(newDib+lineBytes*(height-1-i)+j);
j++;
BYTE r=*(newDib+lineBytes*(height-1-i)+j);
double avg=(b+g+r)/3.0;
if(avg>128) avg=255;
if(avg<=128) avg=0;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
n++;
*(newDib+lineBytes*(height-1-i)+n)=(BYTE)avg;
}
}
}
else
{
AfxMessageBox("只支持8或24位位图");
delete[]newDib;
newDib=NULL;
return;
}
pDoc->GetDibInstance()->SetPixelMatrix(newDib);
delete[]newDib;
newDib=NULL;
m_wndSplitter.ActivateNext();
CDstView*pView=(CDstView*)this->GetActiveView();
pView->OnDraw(pView->GetDC());
m_wndSplitter.ActivateNext();
}