www.pudn.com > imagescale---raw.zip > ImgScaleView.cpp


// ImgScaleView.cpp : implementation of the CImgScaleView class 
// 
 
#include "stdafx.h" 
#include "ImgScale.h" 
 
#include "ImgScaleDoc.h" 
#include "ImgScaleView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#include "ImageGeometry.h" 
#include "ImageScaleDialog.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgScaleView 
 
IMPLEMENT_DYNCREATE(CImgScaleView,  CView) 
 
BEGIN_MESSAGE_MAP(CImgScaleView,  CView) 
	//{{AFX_MSG_MAP(CImgScaleView) 
	ON_COMMAND(IDM_IMAGE_SCALE,  OnImageScale) 
	ON_UPDATE_COMMAND_UI(IDM_IMAGE_SCALE,  OnUpdateImageScale) 
	ON_COMMAND(IDM_IMAGE_RESTORE,  OnImageRestore) 
	ON_UPDATE_COMMAND_UI(IDM_IMAGE_RESTORE,  OnUpdateImageRestore) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgScaleView construction/destruction 
 
CImgScaleView::CImgScaleView() 
{ 
	// TODO: add construction code here 
	m_nWidth = 800; 
	m_nHeight = 600; 
	m_dwOperation = 0L; 
	 
	m_nQuality = 0; 
	m_fsx = m_fsy = 1.0f; 
 
} 
 
CImgScaleView::~CImgScaleView() 
{ 
} 
 
BOOL CImgScaleView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgScaleView drawing 
 
void CImgScaleView::OnDraw(CDC* pDC) 
{ 
	CImgScaleDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
	CDib* pDib = pDoc->m_pDib; 
	if(pDib) 
	{ 
		BeginWaitCursor(); 
		m_nWidth = (int)pDib->GetWidth(); 
		m_nHeight = (int)pDib->GetHeight();  
 
		CDC memDC; 
		memDC.CreateCompatibleDC(pDC); 
		CBitmap ddb; 
		ddb.CreateCompatibleBitmap(pDC, m_nWidth, m_nHeight); 
		CBitmap* pOldBitmap = memDC.SelectObject(&ddb); 
 
		pDib->Draw(memDC.m_hDC, 0, 0, m_nWidth, m_nHeight,  
					0, 0, m_nWidth, m_nHeight, DIB_RGB_COLORS, SRCCOPY); 
		 
		if(m_dwOperation == 0L) 
			pDC->BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY); 
		else 
			Scale(pDC, pDib, 0, 0, m_nWidth, m_nHeight); 
			//Scale(pDC, pDib, 100, 100, 100, 100); 
		 
		memDC.SelectObject(pOldBitmap); 
		ddb.DeleteObject(); 
		EndWaitCursor(); 
	} 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgScaleView diagnostics 
 
#ifdef _DEBUG 
void CImgScaleView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CImgScaleView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CImgScaleDoc* CImgScaleView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImgScaleDoc))); 
	return (CImgScaleDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgScaleView message handlers 
 
void CImgScaleView::OnImageScale()  
{ 
	// TODO: Add your command handler code here 
	CImageScaleDialog dlg; 
	 
	dlg.m_fScalex = m_fsx; 
	dlg.m_fScaley = m_fsy; 
	dlg.m_nQuality = m_nQuality; 
 
 
	int responeDlg = dlg.DoModal(); 
	if(responeDlg == IDOK) 
	{ 
		m_fsx = dlg.m_fScalex; 
		m_fsy = dlg.m_fScaley; 
		m_nQuality = dlg.m_nQuality; 
		m_dwOperation = IMAGE_GEOMETRY_SCALE; 
		Invalidate(); 
	} 
} 
 
void CImgScaleView::OnUpdateImageScale(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	if(m_dwOperation != 0L) 
		pCmdUI ->SetCheck(TRUE); 
	else 
		pCmdUI ->SetCheck(FALSE); 
} 
 
void CImgScaleView::OnImageRestore()  
{ 
	// TODO: Add your command handler code here 
	m_dwOperation = 0L; 
	Invalidate(); 
} 
 
void CImgScaleView::OnUpdateImageRestore(CCmdUI* pCmdUI)  
{ 
	// TODO: Add your command update UI handler code here 
	if(m_dwOperation == 0L) 
		pCmdUI ->SetCheck(TRUE); 
	else 
		pCmdUI ->SetCheck(FALSE);	 
} 
 
void CImgScaleView::Scale(CDC *pDC,  CDib *pDib,  int x,  int y,  int nWidth,  int nHeight) 
{ 
	ASSERT(pDib); 
	 
	//限制处理的区域----防止任意填写数据而使用访问无效 
	if((x > (m_nWidth - 1)) || (y > (m_nHeight - 1))) return ; 
	//实际处理的宽度和高度 
	int w = min(nWidth, m_nWidth - x); 
	int h = min(nHeight, m_nHeight - y); 
	 
	// 32位颜色数据:输入源 
	DWORD dwSizeSrc = m_nWidth * m_nHeight * 4; 
 
	//分配全局内存 32位源数据 
	BYTE* pbyBitsSrc32 =  new BYTE[dwSizeSrc]; 
	if(pbyBitsSrc32 == NULL) return; 
	memset(pbyBitsSrc32,  0 ,  dwSizeSrc); 
 
 
	//CDib类只提供了一个全部数据的函数 
	pDib->GetDdbData32(pbyBitsSrc32); 
 
	//目的地的有效宽度和有效高度 
	int nWidthDst = (int)(m_fsx * nWidth + 0.5f); 
	int nHeightDst = (int)(m_fsy * nHeight + 0.5f); 
	 
	DWORD dwSizeDst = ((DWORD)(nWidthDst * nHeightDst)) * 4; 
	 
	BYTE* pbyBitsDst32 =  new BYTE[dwSizeDst]; 
	if(pbyBitsDst32 == NULL) return; 
	memset(pbyBitsDst32,  0,  dwSizeDst); 
	 
	CImageGeometry* ig = new CImageGeometry(); 
	 
	//设置插值质量 
	if(m_nQuality == 0) 
		ig->SetQuality( IMAGE_GEOMETRY_NEAREST_NEIGHBOR_INTERPOLATE ); 
	else if(m_nQuality == 1) 
		ig->SetQuality( IMAGE_GEOMETRY_BILINEAR_INTERPOLATE ); 
	else if(m_nQuality == 2) 
		ig->SetQuality( IMAGE_GEOMETRY_THREE_ORDER_INTERPOLATE ); 
 
	int t; 
	t=GetTickCount(); 
	ig->Scale(pbyBitsSrc32, x, y, w, h, m_nWidth, m_nHeight, pbyBitsDst32, nWidthDst, nHeightDst); 
	t=GetTickCount()-t; 
 
	CClientDC dc(this); 
	CDC memDC; 
	memDC.CreateCompatibleDC(&dc); 
	HBITMAP hBitmap = ig->CreateDdb(pDC->m_hDC, nWidthDst, nHeightDst, pbyBitsDst32); 
	HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hBitmap); 
	pDC->BitBlt(0, 0, nWidthDst, nHeightDst, &memDC, 0, 0, SRCCOPY); 
	::DeleteObject(hBitmap); 
	memDC.SelectObject(hOldBitmap); 
 
	char TitleData[30]; 
	char NumStr[10]; 
	itoa(t,NumStr,10); 
	strcpy(TitleData,"ImgScale     "); 
	strcat(TitleData,NumStr); 
	strcat(TitleData,"毫秒"); 
	::SetWindowText(::GetParent(this->m_hWnd),TitleData); 
 
	delete ig; 
	delete[] pbyBitsDst32; 
	delete[] pbyBitsSrc32; 
	ReleaseDC(&dc); 
}