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

📄 imageprocessctl.cpp

📁 这是书上的代码
💻 CPP
字号:
// ImageProcessCtl.cpp : Implementation of the CImageProcessCtrl ActiveX Control class.

#include "stdafx.h"
#include "ImageProcess.h"
#include "ImageProcessCtl.h"
#include "ImageProcessPpg.h"
#include "vfw.h"


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


IMPLEMENT_DYNCREATE(CImageProcessCtrl, COleControl)


/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CImageProcessCtrl, COleControl)
	//{{AFX_MSG_MAP(CImageProcessCtrl)
	// NOTE - ClassWizard will add and remove message map entries
	//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_MSG_MAP
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CImageProcessCtrl, COleControl)
	//{{AFX_DISPATCH_MAP(CImageProcessCtrl)
	DISP_FUNCTION(CImageProcessCtrl, "Clear", _Clear, VT_BOOL, VTS_NONE)
	DISP_FUNCTION(CImageProcessCtrl, "ReadBMPFile", _ReadBMPFile, VT_BOOL, VTS_BSTR)
	DISP_FUNCTION(CImageProcessCtrl, "ConvterToGrayBMP", _ConvterToGrayBMP, VT_BOOL, VTS_NONE)
	DISP_FUNCTION(CImageProcessCtrl, "FilterMean", _FilterMean, VT_BOOL, VTS_NONE)
	DISP_FUNCTION(CImageProcessCtrl, "SaveGrayBMPFile", _SaveGrayBMPFile, VT_BOOL, VTS_BSTR)
	DISP_STOCKPROP_APPEARANCE()
	DISP_STOCKPROP_BACKCOLOR()
	//}}AFX_DISPATCH_MAP
	DISP_FUNCTION_ID(CImageProcessCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()


/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CImageProcessCtrl, COleControl)
	//{{AFX_EVENT_MAP(CImageProcessCtrl)
	EVENT_STOCK_CLICK()
	EVENT_STOCK_DBLCLICK()
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CImageProcessCtrl, 1)
	PROPPAGEID(CImageProcessPropPage::guid)
END_PROPPAGEIDS(CImageProcessCtrl)


/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CImageProcessCtrl, "IMAGEPROCESS.ImageProcessCtrl.1",
	0x17a90567, 0xa273, 0x11d6, 0xa0, 0xf2, 0, 0x80, 0xc8, 0xeb, 0xbc, 0x7d)


/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CImageProcessCtrl, _tlid, _wVerMajor, _wVerMinor)


/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DImageProcess =
		{ 0x17a90565, 0xa273, 0x11d6, { 0xa0, 0xf2, 0, 0x80, 0xc8, 0xeb, 0xbc, 0x7d } };
const IID BASED_CODE IID_DImageProcessEvents =
		{ 0x17a90566, 0xa273, 0x11d6, { 0xa0, 0xf2, 0, 0x80, 0xc8, 0xeb, 0xbc, 0x7d } };


/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwImageProcessOleMisc =
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CImageProcessCtrl, IDS_IMAGEPROCESS, _dwImageProcessOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::CImageProcessCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CImageProcessCtrl

BOOL CImageProcessCtrl::CImageProcessCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO: Verify that your control follows apartment-model threading rules.
	// Refer to MFC TechNote 64 for more information.
	// If your control does not conform to the apartment-model rules, then
	// you must modify the code below, changing the 6th parameter from
	// afxRegApartmentThreading to 0.

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_IMAGEPROCESS,
			IDB_IMAGEPROCESS,
			afxRegApartmentThreading,
			_dwImageProcessOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::CImageProcessCtrl - Constructor

CImageProcessCtrl::CImageProcessCtrl()
{
	InitializeIIDs(&IID_DImageProcess, &IID_DImageProcessEvents);

	// TODO: Initialize your control's instance data here.
	m_lpBMPFileData=NULL;
	m_lp24ImgBits=NULL;
	m_lp8ImgBits=NULL;
	m_h8ImgDIB=NULL;

}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::~CImageProcessCtrl - Destructor

CImageProcessCtrl::~CImageProcessCtrl()
{
	// TODO: Cleanup your control's instance data here.
	_Clear();
}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::OnDraw - Drawing function

void CImageProcessCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
	// TODO: Replace the following code with your own drawing code.
	CBrush bkBrush(TranslateColor(GetBackColor()));
	pdc->FillRect(rcBounds,&bkBrush);
	HDC hdc=::GetDC(m_hWnd);
	if (m_lp8ImgBits )
	{
	if ( m_h8ImgDIB )  ::GlobalFree(m_h8ImgDIB);
	m_h8ImgDIB=Create256DIB((DWORD)m_lngWidth,(DWORD)m_lngHeight, m_lp8ImgBits);	//使用vfw 函数来显示DIB
	Show256DIB_vfw(hdc, m_h8ImgDIB);
	}
	else if (m_lp24ImgBits )
	{
	LPBITMAPINFOHEADER lpBMPInfoHeader=(LPBITMAPINFOHEADER) (m_lpBMPFileData+ sizeof(BITMAPFILEHEADER) );
	BITMAPINFO * lpBMPInfo =(BITMAPINFO *) (m_lpBMPFileData+ sizeof(BITMAPFILEHEADER) );
	SetDIBitsToDevice(hdc,0,0,lpBMPInfoHeader->biWidth,lpBMPInfoHeader->biHeight,0,0,0,lpBMPInfoHeader->biHeight,m_lpBMPFileData+14+40,lpBMPInfo,DIB_RGB_COLORS);
	}

}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::DoPropExchange - Persistence support

void CImageProcessCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	// TODO: Call PX_ functions for each persistent custom property.
	PX_Short(pPX,_T("Appearance"),m_sAppearance,1);

}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::OnResetState - Reset control to default state

void CImageProcessCtrl::OnResetState()
{
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange

	// TODO: Reset any other control state here.
}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl::AboutBox - Display an "About" box to the user

void CImageProcessCtrl::AboutBox()
{
	CDialog dlgAbout(IDD_ABOUTBOX_IMAGEPROCESS);
	dlgAbout.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CImageProcessCtrl message handlers

BOOL CImageProcessCtrl::_Clear() 
{
	// TODO: Add your dispatch handler code here

	if ( m_lpBMPFileData )	{
		delete [] m_lpBMPFileData;
		m_lpBMPFileData=NULL;
	}
	if ( m_lp24ImgBits )   	{
		delete [] m_lp24ImgBits;
		m_lp24ImgBits=NULL;
	}
	if ( m_lp8ImgBits )    	{
		delete [] m_lp8ImgBits;
		m_lp8ImgBits=NULL;
	}
	InvalidateControl();
	return TRUE;

}

BOOL CImageProcessCtrl::_ReadBMPFile(LPCTSTR strFileName) 
{
	// TODO: Add your dispatch handler code here
	_Clear(); 
	CFile BitmapFile;
	BOOL blOpen=BitmapFile.Open(strFileName, CFile::modeRead,NULL);
	if( !blOpen )  {
	AfxMessageBox( "读文件失败!");
	return FALSE;
	}
	unsigned int FileLength=BitmapFile.GetLength();
	m_lpBMPFileData = new BYTE[FileLength];
	ASSERT( m_lpBMPFileData!=NULL );
	BitmapFile.Read(m_lpBMPFileData, FileLength);

	LPBITMAPFILEHEADER pBitmapFileHeader = (LPBITMAPFILEHEADER)m_lpBMPFileData;
	LPBITMAPINFOHEADER pBitmapInfoHeader = LPBITMAPINFOHEADER((LPBYTE)m_lpBMPFileData+sizeof(BITMAPFILEHEADER));
	if ( pBitmapFileHeader->bfType != 0x4D42 )  {
	AfxMessageBox( "不支持除BMP之外的文件!");
	delete [] m_lpBMPFileData;
	m_lpBMPFileData=NULL;
	return FALSE;
	}
	if ( pBitmapInfoHeader->biBitCount != 24 )  {
	AfxMessageBox( "不支持除24位真彩的图片!");
	delete [] m_lpBMPFileData;
	m_lpBMPFileData=NULL;
	return FALSE;
	}

	//开始进行类成员的初始化
	m_lngWidth=pBitmapInfoHeader->biWidth;
	m_lngHeight=pBitmapInfoHeader->biHeight;
	//对宽度进行4字节对齐
	m_lng24WidthBytes=(m_lngWidth+m_lngWidth+m_lngWidth+3) & 0xfffffffc;
	m_ulng24BitsCount=m_lng24WidthBytes*m_lngHeight;
	m_lp24ImgBits= new BYTE[m_ulng24BitsCount];
	ASSERT (m_lp24ImgBits!=NULL);
	::memcpy(m_lp24ImgBits,m_lpBMPFileData + ((BITMAPFILEHEADER *)m_lpBMPFileData)->bfOffBits,m_ulng24BitsCount);
	// SetControlSize 是从ColeControl继承来的方法
	SetControlSize( (int)m_lngWidth,(int)m_lngHeight );
	InvalidateControl();
	return TRUE;

}

BOOL CImageProcessCtrl::_ConvterToGrayBMP() 
{
	// TODO: Add your dispatch handler code here
	int i,j;
	if ( m_lp24ImgBits==NULL )	{
	AfxMessageBox( "无24位真彩图象数据!");
	return FALSE;
	}
	//已经存在8位灰度数据
	if ( m_lp8ImgBits ) {
	return TRUE;
	}
	// 0xfffffffc 用二进制表示为1111 1100 
	m_lng8WidthBytes=(m_lngWidth+3) & 0xfffffffc;
	m_ulng8BitsCount=m_lng8WidthBytes*m_lngHeight;
	m_lp8ImgBits=new BYTE[m_ulng8BitsCount];
	ASSERT(m_lp8ImgBits!=NULL);
	::memset(m_lp8ImgBits,0,m_ulng8BitsCount);

	m_lp8ImgBitsMove=m_lp8ImgBits;
	m_lp24ImgBitsMove=m_lp24ImgBits;

	for (j=0;j<m_lngHeight;j++)     {
	m_lp8ImgBitsMove=m_lp8ImgBits+m_lng8WidthBytes*j;
	m_lp24ImgBitsMove=m_lp24ImgBits+m_lng24WidthBytes*j;
		for(i=0;i<m_lngWidth;i++)  	{			*m_lp8ImgBitsMove= (BYTE)(((long)(*m_lp24ImgBitsMove))*0.114+		((long)(*(m_lp24ImgBitsMove+1)))*0.587+((long)(*(m_lp24ImgBitsMove+2)))*0.299);
				m_lp8ImgBitsMove++;
				m_lp24ImgBitsMove+=3;
			}
		}
	
	InvalidateControl();
	return TRUE;

}

BOOL CImageProcessCtrl::_FilterMean() 
{
	// TODO: Add your dispatch handler code here
	if ( m_lp8ImgBits==NULL )
	{	
	AfxMessageBox( "没有灰度数据");
	return FALSE;
	}
	int i,j;
	BYTE bHuiDu;
	LPBYTE lpTemp;
	LPBYTE lpTempMove;
	//申请新的空间来存放一份灰度图像的拷贝
	lpTemp = new BYTE[m_ulng8BitsCount];
	ASSERT ( lpTemp != NULL );
	::memcpy(lpTemp, m_lp8ImgBits, m_ulng8BitsCount);

	for ( j=1;j<m_lngHeight-1;j++ ) 	
	{
		for ( i=1;i<m_lngWidth-1;i++ )	
		{
			lpTempMove = lpTemp+j*m_lng8WidthBytes+i;
			m_lp8ImgBitsMove = m_lp8ImgBits+ j*m_lng8WidthBytes+i;
			bHuiDu=( *(lpTempMove-m_lngWidth-1) + *(lpTempMove-m_lngWidth) + *(lpTempMove-m_lngWidth+1) + *(lpTempMove-1) + *(lpTempMove) + *(lpTempMove+1)                         +
			*(lpTempMove+m_lngWidth-1)              +
			*(lpTempMove+m_lngWidth)                +
			*(lpTempMove+m_lngWidth+1)  ) / 9;
			* m_lp8ImgBitsMove =bHuiDu;
		}
	}
	delete [] lpTemp;
	InvalidateControl();
	return TRUE;

}

BOOL CImageProcessCtrl::_SaveGrayBMPFile(LPCTSTR strFileName) 
{
	// TODO: Add your dispatch handler code here
	CString strName = strFileName;
	CFile bmpFile;
	BOOL bFileOpen=bmpFile.Open(strFileName, CFile::modeCreate | CFile::modeWrite,NULL);
	if ( bFileOpen==0 )
	{
	AfxMessageBox( "创建文件失败!");
	return FALSE;
	}
	if ( m_lp8ImgBits==NULL )
	{	
	AfxMessageBox( "没有灰度数据");
	return FALSE;
	}
	BITMAPFILEHEADER bmpFileHeader={
			0x4D42,
			14+40+1024+m_ulng8BitsCount,
			0,
			0,
			14+40+1024  };
	bmpFile.Write(&bmpFileHeader,14);
	bmpFile.Write(::GlobalLock(m_h8ImgDIB),40+1024+m_ulng8BitsCount);
	bmpFile.Close();
	::GlobalUnlock(m_h8ImgDIB);

	return TRUE;
}

HANDLE CImageProcessCtrl::Create256DIB(DWORD dwWidth, DWORD dwHeight, BYTE *pImgData)
{
	BITMAPINFOHEADER bi;
	LPBITMAPINFOHEADER lpbi;        
	DWORD dwLength;   
	HANDLE hDIB;  
	DWORD dwBytesPerLine;   //每行的字节数
	BYTE * pByte;                    
	int i;                           

	dwBytesPerLine=(dwWidth+3) & 0xfffffffc;
	//填充BMPINFOHEADER;
	bi.biSize=sizeof(BITMAPINFOHEADER);
	bi.biWidth=dwWidth;
	bi.biHeight=dwHeight;
	bi.biPlanes=1;
	bi.biBitCount=8;
	bi.biCompression=BI_RGB;
	bi.biSizeImage=dwBytesPerLine*dwHeight;
	bi.biXPelsPerMeter=0;
	bi.biYPelsPerMeter=0;
	bi.biClrUsed=256;
	bi.biClrImportant=0;
		
	//计算DIB所需要的空间 BITMAPINFOHEADER + Palette + 数据区
	dwLength=bi.biSize+256*4+bi.biSizeImage;
	hDIB=::GlobalAlloc(GHND,dwLength);
	if ( !hDIB )  return NULL;
	lpbi=(LPBITMAPINFOHEADER)::GlobalLock(hDIB);
	//用我们自己的BITMAPINFOHEADER来填充mem的前面的区域
	*lpbi=bi;
	//指针指向调色板开始区域
	lpbi+=1;
	pByte=(BYTE *)lpbi;
	for( i = 0;i < 256 * 4; )
	{
		memset(  pByte+ i,i / 4,3 );
		i += 4;
	}
	//填充数据
	pByte+=256*4;
	memcpy(pByte,pImgData,bi.biSizeImage);
	::GlobalUnlock(hDIB);
	return hDIB;

}

BOOL CImageProcessCtrl::Show256DIB_vfw(HDC hdc, HANDLE hDIB)
{
	//参数:1 DC的句柄  2 DIB数据区的HANDLE
	LPBITMAPINFOHEADER lpBMPinfo = ( LPBITMAPINFOHEADER )::GlobalLock(hDIB);
	HDRAWDIB hdd=::DrawDibOpen();
	::DrawDibDraw(hdd,hdc,0,0,lpBMPinfo->biWidth,lpBMPinfo->biHeight,lpBMPinfo,(LPBYTE)lpBMPinfo+40+1024,0,0,lpBMPinfo->biWidth,lpBMPinfo->biHeight,DDF_BACKGROUNDPAL);
	::DrawDibClose(hdd);
	::GlobalUnlock(hDIB);
	return TRUE;
}

⌨️ 快捷键说明

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