⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convolutionview.cpp

📁 visual c++数字图像与图形处理中的光盘内容
💻 CPP
字号:
// ConvolutionView.cpp : implementation of the CConvolutionView class
//

#include "stdafx.h"
#include "Convolution.h"

#include "ConvolutionDoc.h"
#include "ConvolutionView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "ConvolutionFilter.h"
#include "AreaProcessDialog.h"

/////////////////////////////////////////////////////////////////////////////
// CConvolutionView


IMPLEMENT_DYNCREATE(CConvolutionView,  CView)

BEGIN_MESSAGE_MAP(CConvolutionView,  CView)
	//{{AFX_MSG_MAP(CConvolutionView)
	ON_COMMAND(IDM_KERNEL_CUSTOM,  OnKernelCustom)
	ON_UPDATE_COMMAND_UI(IDM_KERNEL_CUSTOM,  OnUpdateKernelCustom)
	ON_COMMAND(IDM_KERNEL_SELF_DEFINE,  OnKernelSelfDefine)
	ON_UPDATE_COMMAND_UI(IDM_KERNEL_SELF_DEFINE,  OnUpdateKernelSelfDefine)
	ON_COMMAND(IDM_IMAGE_RESTORE,  OnImageRestore)
	ON_UPDATE_COMMAND_UI(IDM_IMAGE_RESTORE,  OnUpdateImageRestore)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CConvolutionView construction/destruction

CConvolutionView::CConvolutionView()
{
	// TODO: add construction code here
	m_nWidth = 800;
	m_nHeight = 600;
	m_dwOperation = 0L;
	m_nWhichRadio = 0;
}

CConvolutionView::~CConvolutionView()
{}

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

	return CView::PreCreateWindow(cs);
}


/////////////////////////////////////////////////////////////////////////////
// CConvolutionView drawing

void CConvolutionView::OnDraw(CDC* pDC)
{
	CConvolutionDoc* 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
			Filter(pDC, pDib, 0, 0, m_nWidth, m_nHeight);
		
		memDC.SelectObject(pOldBitmap);
		ddb.DeleteObject();
		EndWaitCursor();
	}
}

/////////////////////////////////////////////////////////////////////////////
// CConvolutionView diagnostics

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

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

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

/////////////////////////////////////////////////////////////////////////////
// CConvolutionView message handlers

void CConvolutionView::Filter(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 dwSize = m_nWidth * m_nHeight * 4;

	//分配全局内存 32位源数据
	BYTE* pbyBits32 =  new BYTE[dwSize];
	if(pbyBits32 == NULL) return;
	memset(pbyBits32, 0 , dwSize);


	//CDib类只提供了一个全部数据的函数
	pDib->GetDdbData32(pbyBits32);


	//图像区域处理
	CConvolutionFilter* cf = new CConvolutionFilter();
	
	//获取数据后, 其基本参考点变为(0, 0).
	cf->SetOperation(m_dwOperation);
	
	if(m_dwOperation == IMAGE_GENERAL_CONVOLUTION_FILTER)
	{
		/*
		int* pnKernel = new int[21];
		pnKernel[0] = 25; pnKernel[1] = 0; pnKernel[2] = 12;
		pnKernel[3] = 0; pnKernel[4] = 12; pnKernel[5] = 0;
		pnKernel[6] = 25; pnKernel[7] = 12; pnKernel[8] = 0;
		pnKernel[9] = 6; pnKernel[10] = -25; pnKernel[11] = 6;
		pnKernel[12] = 0; pnKernel[13] = 12; pnKernel[14] = 25;
		pnKernel[15] = 0; pnKernel[16] = 12; pnKernel[17] = 0;
		pnKernel[18] = 12; pnKernel[19] = 0; pnKernel[20] = 25;
		*/

		/*
		int* pnKernel = new int[25];
		pnKernel[0] = pnKernel[4] = pnKernel[20] = pnKernel[24] = 16;
		pnKernel[2] = pnKernel[6] = pnKernel[8] = pnKernel[10] = 4;
		pnKernel[14] = pnKernel[16] = pnKernel[18] = pnKernel[22] = 4;
		pnKernel[1] = pnKernel[3] = pnKernel[5] = pnKernel[9] = 0;
		pnKernel[15] = pnKernel[19] = pnKernel[21] = pnKernel[23] = 1;
		pnKernel[7] = pnKernel[11] = pnKernel[13] = pnKernel[17] = 1;
		pnKernel[12] = 0;		
		*/
		int* pnKernel = new int[49];
		pnKernel[0] = pnKernel[6] = pnKernel[42] = pnKernel[48] = 0;
		
		pnKernel[1] = pnKernel[5] = pnKernel[7] = pnKernel[13] = 0;
		pnKernel[35] = pnKernel[41] = pnKernel[43] = pnKernel[47] = 0;

		pnKernel[2] = pnKernel[4] = pnKernel[8] = pnKernel[12] = 4;
		pnKernel[14] = pnKernel[20] = pnKernel[28] = pnKernel[34] = 4;
		pnKernel[36] = pnKernel[40] = pnKernel[44] = pnKernel[46] = 4;
		
		pnKernel[3] = pnKernel[9] = pnKernel[15] = pnKernel[21] = 0;
		pnKernel[27] = pnKernel[33] = pnKernel[39] = pnKernel[45] = 0;
		pnKernel[11] = pnKernel[19] = pnKernel[29] = pnKernel[37] = 0;

		pnKernel[10] = pnKernel[16] = pnKernel[22] = pnKernel[18] = 0;
		pnKernel[26] = pnKernel[32] = pnKernel[38] = pnKernel[30] = 0;

		pnKernel[17] = pnKernel[23] = pnKernel[25] = pnKernel[31] = -1;
		pnKernel[24] = 5;		

		cf->SetKernel(pnKernel, 7, 7);

		//可以释放, 因为CConvolutionFilter类重新建立了卷积核版本
		delete[] pnKernel;
	}

	cf->Filter(pbyBits32, x, y, w, h, m_nWidth, m_nHeight);

	CClientDC dc(this);
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);
	HBITMAP hBitmap = cf->CreateDdb(pDC->m_hDC, m_nWidth, m_nHeight, pbyBits32);
	HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hBitmap);
	pDC->BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
	::DeleteObject(hBitmap);
	memDC.SelectObject(hOldBitmap);

	delete cf;
	delete[] pbyBits32;
	ReleaseDC(&dc);
}

void CConvolutionView::OnKernelCustom() 
{
	// TODO: Add your command handler code here
	CAreaProcessDialog apdDlg;

	apdDlg.m_nOperation = m_nWhichRadio;


	int responeDlg = apdDlg.DoModal();
	if(responeDlg == IDOK)
	{
		m_nWhichRadio = apdDlg.m_nOperation;

		if(m_nWhichRadio == 0)
			m_dwOperation = IMAGE_BLUR_MEAN_SMOOTH_3;
		else if(m_nWhichRadio == 1)
			m_dwOperation = IMAGE_BLUR_MEAN_SMOOTH_5;
		else if(m_nWhichRadio == 2)
			m_dwOperation = IMAGE_LOWPASS_NOISE_REMOVE_3;
		else if(m_nWhichRadio == 3)
			m_dwOperation = IMAGE_LOWPASS_NOISE_REMOVE_5;
		else if(m_nWhichRadio == 4)
			m_dwOperation = IMAGE_HIGHPASS_BASIC_SHARPEN;
		else if(m_nWhichRadio == 5)
			m_dwOperation = IMAGE_HIGHPASS_MODERATE_SHARPEN;
		else if(m_nWhichRadio == 6)
			m_dwOperation = IMAGE_HIGHPASS_EXCESSIVE_SHARPEN;
		else if(m_nWhichRadio == 7)
			m_dwOperation = IMAGE_HIGHPASS_OUTLINE_SHARPEN;
		else if(m_nWhichRadio == 8)
			m_dwOperation = IMAGE_LAPLACIAN_BASIC_DETECT;
		else if(m_nWhichRadio == 9)
			m_dwOperation = IMAGE_LAPLACIAN_MODERATE_DETECT;
		else if(m_nWhichRadio == 10)
			m_dwOperation = IMAGE_LAPLACIAN_EXCESSIVE_DETECT;

		else if(m_nWhichRadio == 11)
			m_dwOperation = IMAGE_GRADIENT_EAST_DETECT;
		else if(m_nWhichRadio == 12)
			m_dwOperation = IMAGE_GRADIENT_SOUTH_DETECT;
		else if(m_nWhichRadio == 13)
			m_dwOperation = IMAGE_GRADIENT_NORTHEAST_DETECT;
		else if(m_nWhichRadio == 14)
			m_dwOperation = IMAGE_GRADIENT_SOUTHEAST_DETECT;

		else if(m_nWhichRadio == 15)
			m_dwOperation = IMAGE_DIFFERENCE_EAST_DETECT;
		else if(m_nWhichRadio == 16)
			m_dwOperation = IMAGE_DIFFERENCE_SOUTH_DETECT;
		else if(m_nWhichRadio == 17)
			m_dwOperation = IMAGE_DIFFERENCE_NORTHEAST_DETECT;
		else if(m_nWhichRadio == 18)
			m_dwOperation = IMAGE_DIFFERENCE_SOUTHEAST_DETECT;

		else if(m_nWhichRadio == 19)
			m_dwOperation = IMAGE_PREWITT_EAST_DETECT;
		else if(m_nWhichRadio == 20)
			m_dwOperation = IMAGE_PREWITT_SOUTH_DETECT;
		else if(m_nWhichRadio == 21)
			m_dwOperation = IMAGE_PREWITT_NORTHEAST_DETECT;
		else if(m_nWhichRadio == 22)
			m_dwOperation = IMAGE_PREWITT_SOUTHEAST_DETECT;

		Invalidate();
	}
	
}

void CConvolutionView::OnUpdateKernelCustom(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if((m_dwOperation != 0) && (m_dwOperation != IMAGE_GENERAL_CONVOLUTION_FILTER))
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);	
}

void CConvolutionView::OnKernelSelfDefine() 
{
	// TODO: Add your command handler code here
	m_dwOperation = IMAGE_GENERAL_CONVOLUTION_FILTER;
	Invalidate();
}

void CConvolutionView::OnUpdateKernelSelfDefine(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_dwOperation == IMAGE_GENERAL_CONVOLUTION_FILTER)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);	
}

void CConvolutionView::OnImageRestore() 
{
	
	// TODO: Add your command handler code here
	m_dwOperation = 0L;
	Invalidate();
	
}

void CConvolutionView::OnUpdateImageRestore(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	if(m_dwOperation == 0L)
		pCmdUI ->SetCheck(TRUE);
	else
		pCmdUI ->SetCheck(FALSE);	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -