www.pudn.com > 图像处理源代码.rar > Task2.cpp


// Task2.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "tuxiang.h" 
#include "Task2.h" 
#include "image.h" 
#include "imgview.h" 
#include "transset.h" 
#include  
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CTask2 property page 
 
IMPLEMENT_DYNCREATE(CTask2, CPropertyPage) 
 
CTask2::CTask2() : CPropertyPage(CTask2::IDD) 
{ 
	//{{AFX_DATA_INIT(CTask2) 
		// NOTE: the ClassWizard will add member initialization here 
	//}}AFX_DATA_INIT 
} 
 
CTask2::~CTask2() 
{ 
} 
 
void CTask2::DoDataExchange(CDataExchange* pDX) 
{ 
	CPropertyPage::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CTask2) 
		// NOTE: the ClassWizard will add DDX and DDV calls here 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CTask2, CPropertyPage) 
	//{{AFX_MSG_MAP(CTask2) 
	ON_BN_CLICKED(IDOPEN, OnOpen) 
	ON_BN_CLICKED(IDCLOSE, OnClose) 
	ON_BN_CLICKED(IDTRANS, OnTrans) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
extern MYIMAGE* pImage; 
extern CImgView *m_ImgView; 
TRANS_COE coef={1.0 , 1.0 , 0.0 , 0.0 , 0.0}; 
 
///////////////////////////////////////////////////////////////////////////// 
// CTask2 message handlers 
 
void CTask2::OnOpen()  
{ 
	if(m_ImgView!=NULL) m_ImgView->ShowWindow (SW_HIDE); 
	if(pImage!=NULL) 
		delete pImage; 
 
	static char BASED_CODE szFilter[] = "图象文件 (*.bmp)|*.bmp"; 
	CString sFileName; 
 
	//显示一个Open File Dialog 
	CFileDialog	opendlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL); 
	int choice=opendlg.DoModal(); 
	if(choice!=IDOK)	//未选择文件,则返回 
		return; 
 
	//读取文件名 
	sFileName=opendlg.GetPathName(); 
	if(opendlg.GetFileExt()=="bmp") 
		pImage=ReadBmp(sFileName,this->m_hWnd); 
	if(m_ImgView==NULL) m_ImgView=new CImgView(pImage,this); 
	else m_ImgView->img = pImage; 
 
	m_ImgView->ShowWindow (SW_SHOWNORMAL); 
	m_ImgView->DisplayImage(); 
} 
 
void CTask2::OnClose()  
{ 
	// TODO: Add your control notification handler code here 
	if(m_ImgView!=NULL) 
	{ 
		m_ImgView->EndDialog(IDOK); 
		m_ImgView=NULL; 
	} 
	if(pImage!=NULL) 
	{ 
		delete pImage; 
		pImage=NULL; 
	}	 
} 
 
//从转换前的点坐标计算转换后的点坐标 
REALPOINT Old2New(const REALPOINT oldp) 
{ 
	REALPOINT newp; 
 
	newp.x=( oldp.x * cos(coef.theta) - oldp.y * sin(coef.theta)) *  
		    coef.xscale +coef.xoff ; 
	newp.y=( oldp.x * sin(coef.theta) + oldp.y * cos(coef.theta)) *  
		    coef.yscale +coef.yoff ; 
 
	return newp; 
} 
 
//从转换后的点坐标计算转换前的点坐标 
REALPOINT New2Old(const REALPOINT newp) 
{ 
	REALPOINT oldp; 
 
	oldp.x = cos(coef.theta)*(newp.x - coef.xoff)/coef.xscale +  
			sin(coef.theta)*(newp.y - coef.yoff)/coef.yscale ; 
	oldp.y = - sin(coef.theta)*(newp.x - coef.xoff)/coef.xscale +  
			cos(coef.theta)*(newp.y - coef.yoff)/coef.yscale ; 
 
	return oldp; 
} 
 
void CTask2::OnTrans()  
{ 
	if(pImage==NULL){ 
		MessageBox("当前无图象显示。"); 
		return; 
	} 
	 
	m_ImgView->ShowWindow(SW_HIDE); 
	CTransSet *setdlg=new CTransSet; 
 
	int choice=setdlg->DoModal(); 
	if(choice!=IDOK) 
		return; 
 
	int oldHeight,oldWidth; 
 
	oldHeight=pImage->Height ; 
	oldWidth=pImage->Width ; 
 
	BYTE* oldimgdata=new BYTE[oldHeight * oldWidth]; 
	memcpy(oldimgdata,pImage->ImgData,oldHeight * oldWidth); 
 
	//设置变换参数 
	if(setdlg->m_bRotate) coef.theta = setdlg->m_rotate * 3.1415926 / 180.0; 
	else coef.theta = 0.0; 
 
	if(setdlg->m_bXoff ) coef.xoff = setdlg->m_xoff ; 
	else coef.xoff = 0.0; 
 
	if(setdlg->m_bXscale ) coef.xscale = setdlg->m_xscale ; 
	else coef.xscale = 1.0; 
 
	if(setdlg->m_bYoff ) coef.yoff = setdlg->m_yoff ; 
	else coef.yoff = 0.0; 
 
	if(setdlg->m_bYscale ) coef.yscale = setdlg->m_yscale ; 
	else coef.yscale = 1.0; 
 
	delete setdlg; 
 
	//定义原图像的四个顶点,以左下脚为坐标原点 
	REALPOINT Vertex[4]; 
	//Bottom Left 
	Vertex[0].x=0.0; 
	Vertex[0].y=0.0; 
	//Top Left 
	Vertex[1].x =0.0; 
	Vertex[1].y =pImage->Height - 1.0; 
	//Bottom Right 
	Vertex[2].x=pImage->Width - 1.0; 
	Vertex[2].y=0.0; 
	//Top Right 
	Vertex[3].x = pImage->Width - 1.0; 
	Vertex[3].y = pImage->Height - 1.0; 
 
	REALPOINT newpoint,oldpoint; 
	double xmax=0.0,ymax=0.0; 
 
	for(int tmp=0;tmp<4;tmp++) 
	{ 
		//转换到以图象中心为坐标原点的坐标系 
		Vertex[tmp].x -= (pImage->Width - 1)/2; 
		Vertex[tmp].y -= (pImage->Height - 1)/2; 
 
		//经图象变换后四个顶点的新坐标,求绝对值最大的X和Y坐标 
		newpoint=Old2New(Vertex[tmp]); 
		if(fabs(newpoint.x) > xmax) xmax=fabs(newpoint.x); 
		if(fabs(newpoint.y) > ymax) ymax=fabs(newpoint.y); 
	} 
 
	//变换后图象的高和宽 
	pImage->Height = 2 * (int)ymax + 1; 
	pImage->Width = 2 * (int)xmax + 1; 
 
	delete pImage->ImgData ; 
	 
	BYTE *newimgdata=new BYTE[pImage->Height * pImage->Width]; 
 
	int u,v; 
	double alpha,beta; 
 
	for(int vert=0;vertHeight;vert++) 
		for(int hori=0;horiWidth;hori++) 
		{ 
			//计算新图中(hori,vert)点对应原图上的坐标点 
			newpoint.x = hori - xmax ; 
			newpoint.y = vert - ymax ; 
			oldpoint = New2Old(newpoint); 
			 
			//转换到以图象左下角点为原点的坐标系 
			oldpoint.x += (oldWidth - 1)/2.0; 
			oldpoint.y += (oldHeight - 1)/2.0; 
 
			//若oldpoint不在原图范围内,设置成白色 
			if(oldpoint.x < 0 || oldpoint.x > oldWidth -1 || 
				   oldpoint.y < 0 || oldpoint.y >oldHeight - 1 ) 
				newimgdata[vert * pImage->Width + hori ] = 255 ;  
			else 
			{ 
				u=(int)oldpoint.x; 
				v=(int)oldpoint.y; 
				alpha=oldpoint.x - u; 
				beta =oldpoint.y - v; 
				newimgdata[vert * pImage->Width + hori ] = (BYTE)( 
					(1.0-alpha)*(1.0-beta)*oldimgdata[v * oldWidth + u] + 
					alpha * (1.0-beta)*oldimgdata[v * oldWidth + u + 1] + 
					(1.0-alpha)* beta *oldimgdata[(v+1) * oldWidth + u] + 
					alpha * beta * oldimgdata[(v+1) * oldWidth + u + 1] ); 
//				newimgdata[vert * pImage->Width + hori ] =  
//					oldimgdata[(int)oldpoint.y * oldWidth + (int)oldpoint.x];  
			} 
		} 
 
	pImage->ImgData = newimgdata; 
 
	delete oldimgdata; 
	m_ImgView->ShowWindow(SW_NORMAL); 
	m_ImgView->DisplayImage (); 
 
}