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

📄 imagedoc.cpp

📁 《Visual C++.NET MFC类库应用详解》程序实例
💻 CPP
字号:
// ImageDoc.cpp : implementation of the CImageDoc class
//

#include "stdafx.h"
#include "Image.h"

#include "ImageDoc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CImageDoc

IMPLEMENT_DYNCREATE(CImageDoc, CDocument)

BEGIN_MESSAGE_MAP(CImageDoc, CDocument)
	//{{AFX_MSG_MAP(CImageDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImageDoc construction/destruction

CImageDoc::CImageDoc()
{
	// TODO: add one-time construction code here

}

CImageDoc::~CImageDoc()
{
}

BOOL CImageDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CImageDoc serialization

void CImageDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CImageDoc diagnostics

#ifdef _DEBUG
void CImageDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CImageDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CImageDoc commands

CDib::CDib()
{
	// Set the Dib pointer to NULL so we know if it's been loaded.
	m_pDib = NULL;
	m_bit24=0;
}

CDib::~CDib()
{
	// If a Dib has been loaded, delete the memory.
	if( m_pDib != NULL )
		delete [] m_pDib;
}

BOOL CDib::Load( const char *pszFilename )
{
	CFile cf;
	// Attempt to open the Dib file for reading.
	if( !cf.Open( pszFilename, CFile::modeRead ) )
		return( FALSE );
	// Get the size of the file and store
	// in a local variable. Subtract the
	// size of the BITMAPFILEHEADER structure
	// since we won't keep that in memory.
	DWORD dwDibSize;
	dwDibSize =	cf.GetLength() - sizeof( BITMAPFILEHEADER );
	// Attempt to allocate the Dib memory.
	unsigned char *pDib;
	pDib = new unsigned char [dwDibSize];
	if( pDib == NULL )
		return( FALSE );

	BITMAPFILEHEADER BFH;
	// Read in the Dib header and data.
		// Did we read in the entire BITMAPFILEHEADER?
		if(cf.Read(&BFH,sizeof(BITMAPFILEHEADER))!= sizeof(BITMAPFILEHEADER)||
			BFH.bfType != 'MB' ||// Is the type 'MB'?
			// Did we read in the remaining data?
			cf.Read( pDib, dwDibSize)!= dwDibSize)
		{
			// Delete the memory if we had any
			// errors and return FALSE.
			delete [] pDib;
			return( FALSE );
		}

	// If we got to this point, the Dib has been
	// loaded. If a Dib was already loaded into
	// this class, we must now delete it.
	if( m_pDib != NULL )
		delete m_pDib;

	// Store the local Dib data pointer and
	// Dib size variables in the class member
	// variables.
	m_pDib = pDib;
	m_dwDibSize = dwDibSize;

	// Pointer our BITMAPINFOHEADER and RGBQUAD
	// variables to the correct place in the Dib data.
	m_pBIH = (BITMAPINFOHEADER *) m_pDib;
	m_pPalette =(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];

	// Calculate the number of palette entries.
	m_nPaletteEntries = 1 << m_pBIH->biBitCount;
	if( m_pBIH->biBitCount > 8 )
		m_nPaletteEntries = 0;
	else if( m_pBIH->biClrUsed != 0 )
		m_nPaletteEntries = m_pBIH->biClrUsed;

	// Point m_pDibBits to the actual Dib bits data.
	m_pDibBits = &m_pDib[sizeof(BITMAPINFOHEADER)+
		m_nPaletteEntries*sizeof(RGBQUAD)];

	// If we have a valid palette, delete it.
	if( m_Palette.GetSafeHandle() != NULL )
		m_Palette.DeleteObject();
	// If there are palette entries, we'll need
	// to create a LOGPALETTE then create the
	// CPalette palette.
	if( m_nPaletteEntries != 0 )
	{
		// Allocate the LOGPALETTE structure.
		LOGPALETTE *pLogPal = (LOGPALETTE *) new char[sizeof(LOGPALETTE)+
				m_nPaletteEntries*sizeof(PALETTEENTRY)];
		if( pLogPal != NULL )
		{
			// Set the LOGPALETTE to version 0x300
			// and store the number of palette entries.
			pLogPal->palVersion = 0x300;
			pLogPal->palNumEntries = m_nPaletteEntries;

			// Store the RGB values into each PALETTEENTRY element.
			for( int i=0; i<m_nPaletteEntries; i++ )
			{
				pLogPal->palPalEntry[i].peRed =	m_pPalette[i].rgbRed;
				pLogPal->palPalEntry[i].peGreen = m_pPalette[i].rgbGreen;
				pLogPal->palPalEntry[i].peBlue = m_pPalette[i].rgbBlue;
			}

			// Create the CPalette object and
			// delete the LOGPALETTE memory.
			m_Palette.CreatePalette( pLogPal );
			delete [] pLogPal;
		}
	}

	if(m_pBIH->biBitCount != 24)
	{
		AfxMessageBox("The file is not a 24_bit bitmap!");
		m_bit24=0;
	}
    else
		m_bit24=1;

	col=m_pBIH->biWidth;
	row=m_pBIH->biHeight;
	DWORD offset=BFH.bfOffBits;

    if(m_bit24==1)
	{    
	    for(LONG i=0;i<1024;i++)
		{
		    data[i]=new RGBData[1024];
		    for(LONG j=0;j<1024;j++)
			{
			    data[i][j].Blue=0;
			    data[i][j].Green=0;
			    data[i][j].Red=0;
			}
		}
	    cf.Seek(offset,CFile::begin);
	    for(LONG y=row-1;y>=0;y--)
            cf.Read(data[y],col*3);
	    cf.Close();
	}

	return( TRUE );
}

BOOL CDib::Save( const char *pszFilename )
{

	// If we have no data, we can't save.
	if( m_pDib == NULL )
		return( FALSE );
	CFile cf;
	// Attempt to create the file.
	if( !cf.Open( pszFilename,CFile::modeCreate | CFile::modeWrite ))
		return( FALSE );
	
	// create a BITMAPFILEHEADER with the correct data.
	BITMAPFILEHEADER BFH;
	memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
	BFH.bfType = 'MB';
	BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
	BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
			sizeof( BITMAPINFOHEADER ) +
			m_nPaletteEntries * sizeof( RGBQUAD );

	// Write the BITMAPFILEHEADER and the Dib data.
	cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
	cf.Write( m_pDib, m_dwDibSize );

	return( TRUE );
}

BOOL CDib::Draw( CDC *pDC, int nX, int nY)
{

	// If we have not data we can't draw.
	if( m_pDib == NULL )
		return( FALSE );
	
	// Use StretchDIBits to draw the Dib.
	StretchDIBits( pDC->m_hDC, nX, nY,
		m_pBIH->biWidth, m_pBIH->biHeight,
		0, 0,
		m_pBIH->biWidth, m_pBIH->biHeight,
		m_pDibBits,
		(BITMAPINFO *) m_pBIH,
		BI_RGB, SRCCOPY );
	
	return( TRUE );
}

BOOL CDib::SetPalette( CDC *pDC )
{
	// If we have not data, 
	// we won't want to set the palette.
	if( m_pDib == NULL )
		return( FALSE );

	// Check to see if we have a palette handle. 
	// For Dibs greater than 8 bits, this will be NULL.
	if( m_Palette.GetSafeHandle() == NULL )
		return( TRUE );

	// Select the palette, realize the palette,
	// then finally restore the old palette.
	CPalette *pOldPalette;
	pOldPalette = pDC->SelectPalette( &m_Palette, FALSE );
	pDC->RealizePalette();
	pDC->SelectPalette( pOldPalette, FALSE );

	return( TRUE );
}

void CDib::Show(CDC *pDC)
{
	for(LONG y=0;y<row;y++)
	    SetDIBitsToDevice(pDC->GetSafeHdc(),
		     0,y,col,1,0,0,0,1,
			 data[y],(BITMAPINFO *) m_pBIH,
			 DIB_RGB_COLORS);
}

BOOL CDib::Add()
{
	double a=-0.001;
	for(LONG y=0;y<row;y++)
		for(LONG x=0;x<col;x++)
		{
			data[y][x].Blue=(INT)(data[y][x].Blue+
				a*data[y][x].Blue*(255-data[y][x].Blue));
			data[y][x].Green=(INT)(data[y][x].Green+
				a*data[y][x].Green*(255-data[y][x].Green));
			data[y][x].Red=(INT)(data[y][x].Red+
				a*data[y][x].Red*(255-data[y][x].Red));
		}
	return TRUE;
}

BOOL CDib::Invert()
{
	RGBData Tempdata;
	for(long y=0;y<row/2;y++)
		for(long x=0;x<col;x++)
		{
			Tempdata=data[y][x];
			data[y][x]=data[row-1-y][x];
			data[row-1-y][x]=Tempdata;
		}
	return TRUE;	
}
BOOL CDib::Temp(int x,int y,int w[][3])
{
	return abs(data[x-1][y-1].Red*w[0][0]+
	       data[x-1][y].Red*w[0][1]+
	       data[x-1][y+1].Red*w[0][2]+
	       data[x][y-1].Red*w[1][0]+
	       data[x][y].Red*w[1][1]+
	       data[x][y+1].Red*w[1][2]+
	       data[x+1][y-1].Red*w[2][0]+
	       data[x+1][y].Red*w[2][1]+
		   data[x+1][y+1].Red*w[2][2]);
}

BOOL CDib::Edge_Laplace(int ival)
{
    RGBData *data1[1024];
	for(LONG i=0;i<row;i++)
	{
		data1[i]=new RGBData[col];
		for(LONG j=0;j<col;j++)
		{
			data1[i][j].Blue=data[i][j].Blue;
			data1[i][j].Green=data[i][j].Green;
			data1[i][j].Red=data[i][j].Red;
		}
	}
	int x,y;
	int static mode[3][3]={{-1,-1,-1},{-1,8,-1},{-1,-1,-1}};
	for(y=2;y<row-2;y++)
		for(x=2;x<col-2;x++)
		{
			if(Temp(y,x,mode)<ival)
			{
				data1[y][x].Blue=255;
				data1[y][x].Red=255;
				data1[y][x].Green=255;
			}
			else
			{
				data1[y][x].Blue=data[y][x].Blue;
				data1[y][x].Red=data[y][x].Red;
				data1[y][x].Green=data[y][x].Green;
			}
		}
	for(i=0;i<row;i++)
		for(LONG j=0;j<col;j++)
		{
			data[i][j].Blue=data1[i][j].Blue;
			data[i][j].Green=data1[i][j].Green;
			data[i][j].Red=data1[i][j].Red;
		}

	for(i=0;i<row;i++)
		delete []data1[i];
	
	return(true);
}

void CDib::Edge_Sobel()
{
    RGBData *data1[1024];
	for(LONG i=0;i<row;i++)
	{
		data1[i]=new RGBData[col];
		for(LONG j=0;j<col;j++)
		{
			data1[i][j].Blue=data[i][j].Blue;
			data1[i][j].Green=data[i][j].Green;
			data1[i][j].Red=data[i][j].Red;
		}
	}

	int x,y;
	int static modex[3][3]={{-1,-2,-1},{0,0,0},{1,2,1}};
	int static modey[3][3]={{-1,0,1},{-2,0,2},{-1,0,1}};
   
	int ival;
	for(y=2;y<row-2;y++)
		for(x=2;x<col-2;x++)
		{
			if(Temp(y,x,modex)<Temp(y,x,modey))
				ival=Temp(y,x,modey);
			else
				ival=Temp(y,x,modex);
			data1[y][x].Blue=255-ival;
			data1[y][x].Red=255-ival;
			data1[y][x].Green=255-ival;
		}
	for(i=0;i<row;i++)
		for(LONG j=0;j<col;j++)
		{
			data[i][j].Blue=data1[i][j].Blue;
			data[i][j].Green=data1[i][j].Green;
			data[i][j].Red=data1[i][j].Red;
		}
	for(i=0;i<row;i++)
		delete []data1[i];
		
}

⌨️ 快捷键说明

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