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