📄 imageprocessctl.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 + -