www.pudn.com > improc.rar > ImgprocView.cpp


// ImgprocView.cpp : implementation of the CImgprocView class 
// 
 
#include "stdafx.h" 
#include "Imgproc.h" 
 
#include "ImgprocDoc.h" 
#include "ImgprocView.h" 
#include "mainfrm.h" 
#include "cO.h" 
#include "dibapi.h" 
#include "FreTrans.h" 
#include "edgecontour.h" 
#include "TemplateTrans.h" 
#include "filter.h" 
#include "ColorTable.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView 
 
IMPLEMENT_DYNCREATE(CImgprocView, CView) 
 
BEGIN_MESSAGE_MAP(CImgprocView, CView) 
	//{{AFX_MSG_MAP(CImgprocView) 
	ON_COMMAND(ID_RGB_CHANGING, OnRgbChanging) 
	ON_COMMAND(ID_FREL_TRAN, OnFrelTran) 
	ON_COMMAND(ID_EDGE_ROBERT, OnEdgeRobert) 
	ON_COMMAND(ID_SOBELL, OnSobell) 
	ON_COMMAND(ID_MID_FILTER, OnMidFilter) 
	ON_COMMAND(ID_FREL_PFILTER, OnFrelPfilter) 
	ON_COMMAND(ID_DBDCHANGE, OnDbdchange) 
	ON_COMMAND(ID_EVENVALUE, OnEvenvalue) 
	ON_COMMAND(ID_COLORCON, OnColorcon) 
	//}}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() 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView construction/destruction 
 
CImgprocView::CImgprocView() 
{ 
	// TODO: add construction code here 
 
} 
 
CImgprocView::~CImgprocView() 
{ 
} 
 
BOOL CImgprocView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView drawing 
 
void CImgprocView::OnDraw(CDC* pDC) 
{ 
		// 显示等待光标 
	BeginWaitCursor(); 
 
	CImgprocDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
		// 获取DIB 
	HDIB hDIB = pDoc->GetHDIB(); 
	 
	// 判断DIB是否为空 
	if (hDIB != NULL) 
	{ 
		LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
		 
		// 获取DIB宽度 
		int cxDIB = (int) ::DIBWidth(lpDIB); 
		 
		// 获取DIB高度 
		int cyDIB = (int) ::DIBHeight(lpDIB); 
 
		::GlobalUnlock((HGLOBAL) hDIB); 
		 
		CRect rcDIB; 
		rcDIB.top = rcDIB.left = 0; 
		rcDIB.right = cxDIB; 
		rcDIB.bottom = cyDIB; 
		 
		CRect rcDest; 
		 
		// 判断是否是打印 
		if (pDC->IsPrinting()) 
		{ 
			// 是打印,计算输出图像的位置和大小,以便符合页面 
			 
			// 获取打印页面的水平宽度(象素) 
			int cxPage = pDC->GetDeviceCaps(HORZRES); 
			 
			// 获取打印页面的垂直高度(象素) 
			int cyPage = pDC->GetDeviceCaps(VERTRES); 
			 
			// 获取打印机每英寸象素数 
			int cxInch = pDC->GetDeviceCaps(LOGPIXELSX); 
			int cyInch = pDC->GetDeviceCaps(LOGPIXELSY); 
			 
			// 计算打印图像大小(缩放,根据页面宽度调整图像大小) 
			rcDest.top = rcDest.left = 0; 
			rcDest.bottom = (int)(((double)cyDIB * cxPage * cyInch) 
					/ ((double)cxDIB * cxInch)); 
			rcDest.right = cxPage; 
			 
			// 计算打印图像位置(垂直居中) 
			int temp = cyPage - (rcDest.bottom - rcDest.top); 
			rcDest.bottom += temp/2; 
			rcDest.top += temp/2; 
 
		} 
		else    
		// 非打印 
		{ 
			// 不必缩放图像 
			rcDest = rcDIB; 
		} 
		 
		// 输出DIB 
		::PaintDIB(pDC->m_hDC, &rcDest, pDoc->GetHDIB(), 
			&rcDIB, pDoc->GetDocPalette()); 
	} 
	 
	// 恢复正常光标 
	EndWaitCursor(); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView printing 
 
BOOL CImgprocView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CImgprocView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CImgprocView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView diagnostics 
 
#ifdef _DEBUG 
void CImgprocView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CImgprocView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CImgprocDoc* CImgprocView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImgprocDoc))); 
	return (CImgprocDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CImgprocView message handlers 
 
LRESULT CImgprocView::OnDoRealize(WPARAM wParam, LPARAM) 
{ 
	ASSERT(wParam != NULL); 
 
	// 获取文档 
 CImgprocDoc* pDoc = GetDocument(); 
	 
	// 判断DIB是否为空 
	if (pDoc->GetHDIB() == NULL) 
	{ 
		// 直接返回 
		return 0L; 
	} 
	 
	// 获取Palette 
	CPalette* pPal = pDoc->GetDocPalette(); 
	if (pPal != NULL) 
	{ 
		// 获取MainFrame 
		CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd; 
		ASSERT_KINDOF(CMainFrame, pAppFrame); 
		 
		CClientDC appDC(pAppFrame); 
 
		// All views but one should be a background palette. 
		// wParam contains a handle to the active view, so the SelectPalette 
		// bForceBackground flag is FALSE only if wParam == m_hWnd (this view) 
		CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd); 
		 
		if (oldPalette != NULL) 
		{ 
			UINT nColorsChanged = appDC.RealizePalette(); 
			if (nColorsChanged > 0) 
				pDoc->UpdateAllViews(NULL); 
			appDC.SelectPalette(oldPalette, TRUE); 
		} 
		else 
		{ 
			TRACE0("\tCCh1_1View::OnPaletteChanged中调用SelectPalette()失败!\n"); 
		} 
	} 
	 
	return 0L; 
 
} 
 
void CImgprocView::OnEditCopy() 
{ 
	// 复制当前图像 
 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 打开剪贴板 
	if (OpenClipboard()) 
	{ 
		// 更改光标形状 
		BeginWaitCursor(); 
		 
		// 清空剪贴板 
		EmptyClipboard(); 
		 
		// 复制当前图像到剪贴板 
		SetClipboardData (CF_DIB, CopyHandle((HANDLE) pDoc->GetHDIB()) ); 
		 
		// 关闭剪贴板 
		CloseClipboard(); 
		 
		// 恢复光标 
		EndWaitCursor(); 
	} 
 
} 
 
void CImgprocView::OnUpdateEditCopy(CCmdUI *pCmdUI) 
{ 
	// 如果当前DIB对象不空,复制菜单项有效 
	pCmdUI->Enable(GetDocument()->GetHDIB() != NULL); 
 
} 
 
 
void CImgprocView::OnRgbChanging()  
{ 
	// TODO: Add your command handler code here 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类推) 
/*	if (::DIBNumColors(lpDIB) != 256) 
	{ 
		// 提示用户 
		MessageBox("目前只支持256色位图的平移!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	}*/ 
	 
	int dr; 
	int db; 
	int dg; 
	int dy; 
 
	 
	// 创建对话框 
	CcO rgbCha; 
	 
	// 初始化变量值 
	rgbCha.m_db = 0; 
	rgbCha.m_dg = 0; 
	rgbCha.m_dr=0; 
	rgbCha.m_y=0; 
	 
	// 显示对话框,提示用户设定平移量 
	if (rgbCha.DoModal() != IDOK) 
	{ 
		// 返回 
		return; 
	} 
	 
	// 获取用户设定的平移量 
	db=rgbCha.m_db; 
	dg=rgbCha.m_dg; 
	dr=rgbCha.m_dr; 
	dy=rgbCha.m_y; 
 
	 
	// 删除对话框 
	delete rgbCha;	 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 调用TranslationDIB()函数平移DIB 
	if (::AdjustRGB(lpDIB,dr,dg,db)) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnFrelTran()  
{ 
	// TODO: Add your command handler code here 
	// 图像付立叶变换 
	 
	// 获取文档	 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
	 
	// 指向DIB象素指针 
	LPSTR    lpDIBBits; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的付立叶变换,其它的可以类推) 
/*	if (::DIBNumColors(lpDIB) != 256) 
	{ 
		// 提示用户 
		MessageBox("目前只支持256色位图的付立叶变换!", "系统提示" , 
			MB_ICONINFORMATION | MB_OK); 
		 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	}*/ 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
	 
	// 调用Fourier()函数进行付立叶变换 
	if (::Fourier(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB))) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
		 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnEdgeRobert()  
{ 
	// TODO: Add your command handler code here 
		//Robert边缘检测运算 
 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的边缘检测,其它的可以类推) 
	if (::DIBNumColors(lpDIB) != 256) 
	{ 
		// 提示用户 
		MessageBox("目前只支持256色位图的运算!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	} 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 调用RobertDIB()函数对DIB进行边缘检测 
	if (RobertDIB(lpDIBBits, WIDTHBYTES(::DIBWidth(lpDIB) * 8), ::DIBHeight(lpDIB))) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnSobell()  
{ 
	// TODO: Add your command handler code here 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的边缘检测,其它的可以类推) 
/*	if (::DIBNumColors(lpDIB) != 256) 
	{ 
		// 提示用户 
		MessageBox("目前只支持256色位图的运算!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	}*/ 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 调用SobelDIB()函数对DIB进行边缘检测 
	if (SobelDIB(lpDIBBits, WIDTHBYTES(::DIBWidth(lpDIB) * 8), ::DIBHeight(lpDIB))) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnMidFilter()  
{ 
	// TODO: Add your command handler code here 
		// 中值滤波 
	 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
	 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 滤波器的高度 
	int iFilterH; 
	 
	// 滤波器的宽度 
	int iFilterW; 
	 
	// 中心元素的X坐标 
	int iFilterx; 
	 
	// 中心元素的Y坐标 
	int iFiltery; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的中值滤波,其它的可以类推) 
 
	// 创建对话框 
	Cfilter dlgPara; 
	 
	// 初始化变量值 
 
	dlgPara.m_iFilterH= 3; 
	dlgPara.m_iFilterW = 1; 
	dlgPara.m_iFilterx = 0; 
	dlgPara.m_iFilery = 1; 
	 
	// 显示对话框,提示用户设定平移量 
	if (dlgPara.DoModal() != IDOK) 
	{ 
		// 返回 
		return; 
	} 
	 
	// 获取用户的设定 
	iFilterH = dlgPara.m_iFilterH; 
	iFilterW = dlgPara.m_iFilterW; 
	iFilterx = dlgPara.m_iFilterx; 
	iFiltery = dlgPara.m_iFilery; 
	 
	// 删除对话框 
	delete dlgPara;	 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
	 
	// 调用MedianFilter()函数中值滤波 
	if (::MedianFilter(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),  
		  iFilterH, iFilterW, iFilterx, iFiltery)) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
 
void CImgprocView::OnFrelPfilter()  
{ 
	 	// TODO: Add your command handler code here 
 	// 图像付立叶逆变换 
 	 
 	// 获取文档 
 	CImgprocDoc* pDoc = GetDocument(); 
 	 
 	// 指向DIB的指针 
 	LPSTR	lpDIB; 
 	 
 	// 指向DIB象素指针 
 	LPSTR    lpDIBBits; 
 	 
 	// 锁定DIB 
 	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
 	 
 	// 找到DIB图像象素起始位置 
 	lpDIBBits = ::FindDIBBits(lpDIB); 
 	 
 	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的付立叶变换,其它的可以类推) 
 
 	 
 	// 更改光标形状 
 	BeginWaitCursor(); 
 	 
 	// 调用Fourier()函数进行付立叶变换 
 	if (::IFourier(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB))) 
 	{ 
 		 
 		// 设置脏标记 
 		pDoc->SetModifiedFlag(TRUE); 
 		 
 		// 更新视图 
 		pDoc->UpdateAllViews(NULL); 
 	} 
 	else 
 	{ 
 		// 提示用户 
 		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
 	} 
 	 
 	// 解除锁定 
 	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 	 
 	// 恢复光标 
 	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnDbdchange()  
{ 
	// TODO: Add your command handler code here 
		CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平移,其它的可以类推) 
	 
 
	int dy; 
 
	 
	// 创建对话框 
	CcO rgbCha; 
	 
	// 初始化变量值 
 
	rgbCha.m_y=0; 
	 
	// 显示对话框,提示用户设定平移量 
	if (rgbCha.DoModal() != IDOK) 
	{ 
		// 返回 
		return; 
	} 
	 
	// 获取用户设定的平移量 
 
	dy=rgbCha.m_y; 
 
	 
	// 删除对话框 
	delete rgbCha;	 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 调用TranslationDIB()函数平移DIB 
	if (::AdjustBrightness(lpDIB,dy)) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
	 
 
//均值滤波 
void CImgprocView::OnEvenvalue()  
{ 
	// TODO: Add your command handler code here 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
	 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 模板高度 
	int		iTempH=3; 
	 
	// 模板宽度 
	int		iTempW=3; 
	 
	// 模板系数 
	FLOAT	fTempC=(FLOAT) (1.0 / 9.0); 
	 
	// 模板中心元素X坐标 
	int		iTempMX=1; 
	 
	// 模板中心元素Y坐标 
	int		iTempMY=1; 
	 
	// 模板元素数组 
	FLOAT	aValue[9]; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB); 
	 
	// 判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图的平滑,其它的可以类推) 
/*	if (::DIBNumColors(lpDIB) != 256) 
	{ 
		// 提示用户 
		MessageBox("目前只支持256色位图的平滑!", "系统提示" ,  
			MB_ICONINFORMATION | MB_OK); 
		 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	}*/ 
		aValue[0] = 1.0; 
	aValue[1] = 1.0; 
	aValue[2] = 1.0; 
	aValue[3] = 1.0; 
	aValue[4] = 1.0; 
	aValue[5] = 1.0; 
	aValue[6] = 1.0; 
	aValue[7] = 1.0; 
	aValue[8] = 1.0; 
	BeginWaitCursor(); 
	 
	// 调用Template()函数平滑DIB 
	if (::Template(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB),  
		  iTempH, iTempW, iTempMX, iTempMY, aValue, fTempC)) 
	{ 
		 
		// 设置脏标记 
		pDoc->SetModifiedFlag(TRUE); 
 
		// 更新视图 
		pDoc->UpdateAllViews(NULL); 
	} 
	else 
	{ 
		// 提示用户 
		MessageBox("分配内存失败!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
	} 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
} 
 
void CImgprocView::OnColorcon()  
{ 
	// TODO: Add your command handler code here 
	// 获取文档 
	CImgprocDoc* pDoc = GetDocument(); 
	 
	// 指向DIB的指针 
	LPSTR	lpDIB; 
	 
	// 锁定DIB 
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB()); 
	 
	// 颜色表中的颜色数目 
	WORD wNumColors; 
	 
	// 获取DIB中颜色表中的颜色数目 
	wNumColors = ::DIBNumColors(lpDIB); 
	 
	// 判断是否是8-bpp位图 
	if (wNumColors != 256) 
	{ 
		// 提示用户 
		MessageBox("非256色位图!", "系统提示" , MB_ICONINFORMATION | MB_OK); 
		 
		// 解除锁定 
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
		 
		// 返回 
		return; 
	} 
	 
	// 更改光标形状 
	BeginWaitCursor(); 
	 
	// 指向DIB象素指针 
	LPSTR   lpDIBBits; 
	 
	// 指向DIB象素的指针 
	BYTE *	lpSrc; 
	 
	// 循环变量 
	LONG	i; 
	LONG	j; 
	 
	// 图像宽度 
	LONG	lWidth; 
	 
	// 图像高度 
	LONG	lHeight; 
	 
	// 图像每行的字节数 
	LONG	lLineBytes; 
	 
	// 指向BITMAPINFO结构的指针(Win3.0) 
	LPBITMAPINFO lpbmi; 
	 
	// 指向BITMAPCOREINFO结构的指针 
	LPBITMAPCOREINFO lpbmc; 
	 
	// 表明是否是Win3.0 DIB的标记 
	BOOL bWinStyleDIB; 
	 
	// 获取指向BITMAPINFO结构的指针(Win3.0) 
	lpbmi = (LPBITMAPINFO)lpDIB; 
	 
	// 获取指向BITMAPCOREINFO结构的指针 
	lpbmc = (LPBITMAPCOREINFO)lpDIB; 
	 
	// 灰度映射表 
	BYTE bMap[256]; 
	 
	// 判断是否是WIN3.0的DIB 
	bWinStyleDIB = IS_WIN30_DIB(lpDIB); 
	 
	// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板 
	for (i = 0; i < 256; i ++) 
	{ 
		if (bWinStyleDIB) 
		{ 
			// 计算该颜色对应的灰度值 
			bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed + 
						     0.587 * lpbmi->bmiColors[i].rgbGreen + 
					         0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5); 
			 
			// 更新DIB调色板红色分量 
			lpbmi->bmiColors[i].rgbRed = i; 
			 
			// 更新DIB调色板绿色分量 
			lpbmi->bmiColors[i].rgbGreen = i; 
			 
			// 更新DIB调色板蓝色分量 
			lpbmi->bmiColors[i].rgbBlue = i; 
			 
			// 更新DIB调色板保留位 
			lpbmi->bmiColors[i].rgbReserved = 0; 
		} 
		else 
		{ 
			// 计算该颜色对应的灰度值 
			bMap[i] = (BYTE)(0.299 * lpbmc->bmciColors[i].rgbtRed + 
						     0.587 * lpbmc->bmciColors[i].rgbtGreen + 
					         0.114 * lpbmc->bmciColors[i].rgbtBlue + 0.5); 
			 
			// 更新DIB调色板红色分量 
			lpbmc->bmciColors[i].rgbtRed = i; 
			 
			// 更新DIB调色板绿色分量 
			lpbmc->bmciColors[i].rgbtGreen = i; 
			 
			// 更新DIB调色板蓝色分量 
			lpbmc->bmciColors[i].rgbtBlue = i; 
		} 
	} 
 
	// 找到DIB图像象素起始位置 
	lpDIBBits = ::FindDIBBits(lpDIB);	 
	 
	// 获取图像宽度 
	lWidth = ::DIBWidth(lpDIB); 
	 
	// 获取图像高度 
	lHeight = ::DIBHeight(lpDIB); 
	 
	// 计算图像每行的字节数 
	lLineBytes = WIDTHBYTES(lWidth * 8); 
	 
	// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值) 
	// 每行 
	for(i = 0; i < lHeight; i++) 
	{ 
		// 每列 
		for(j = 0; j < lWidth; j++) 
		{ 
			// 指向DIB第i行,第j个象素的指针 
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j; 
			 
			// 变换 
			*lpSrc = bMap[*lpSrc]; 
		} 
	} 
	 
	// 替换当前调色板为灰度调色板 
	pDoc->GetDocPalette()->SetPaletteEntries(0, 256, (LPPALETTEENTRY) ColorsTable[0]); 
	 
	// 设置脏标记 
	pDoc->SetModifiedFlag(TRUE); 
	 
	// 实现新的调色板 
	OnDoRealize((WPARAM)m_hWnd,0); 
	 
	// 更新视图 
	pDoc->UpdateAllViews(NULL); 
	 
	// 解除锁定 
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB()); 
 
	// 恢复光标 
	EndWaitCursor(); 
	 
}