www.pudn.com > zhifangtu.rar > DipDoc.cpp
// DipDoc.cpp : implementation of the CDipDoc class
//
#include "stdafx.h"
#include "Dip.h"
#include "DipDoc.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "DipView.h"
#include "BmpFileInfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDipDoc
extern char szFilter[];
IMPLEMENT_DYNCREATE(CDipDoc, CDocument)
BEGIN_MESSAGE_MAP(CDipDoc, CDocument)
//{{AFX_MSG_MAP(CDipDoc)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FILE_SAVE, OnFileSave)
ON_COMMAND(ID_FILE_NEW, OnFileNew)
ON_COMMAND(ID_BMPINFO, OnBmpinfo)
ON_COMMAND(ID_ZHIFANGTU, OnZhifangtu)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDipDoc construction/destruction
CDipDoc::CDipDoc()
{
// TODO: add one-time construction code here
m_pImageObject = NULL;
m_bImageLoaded = FALSE;
m_nZhifang=FALSE;
}
CDipDoc::~CDipDoc()
{
if(m_pImageObject != NULL)
{
delete m_pImageObject;
m_pImageObject = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// CDipDoc serialization
void CDipDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDipDoc diagnostics
#ifdef _DEBUG
void CDipDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CDipDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDipDoc commands
void CDipDoc::OnFileOpen()
{
// TODO: Add your command handler code here
static int nIndex = 1;
CFileDialog FileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter );
FileDlg.m_ofn.nFilterIndex = (DWORD)nIndex;
if( FileDlg.DoModal() == IDOK )
{
CString strPathName = FileDlg.GetPathName();
AfxGetApp()->OpenDocumentFile(strPathName);
nIndex = (int) FileDlg.m_ofn.nFilterIndex;
if(!LoadImageToDocument())
{
AfxMessageBox("无法载入图像文件!");
return;
}
}
}
void CDipDoc::OnFileSave()
{
// TODO: Add your command handler code here
static int nIndex = 1;
CFileDialog DialogSaveAs( FALSE, NULL, m_pImageObject->GetImageName(),
OFN_HIDEREADONLY, szFilter );
DialogSaveAs.m_ofn.nFilterIndex = (DWORD) nIndex;
if( DialogSaveAs.DoModal() == IDOK )
{
CMainFrame *pMainFrame = ( CMainFrame * )AfxGetMainWnd();
CChildFrame *pChildFrame = ( CChildFrame * )pMainFrame->MDIGetActive();
CDipView *pDipView = ( CDipView * )pChildFrame->GetActiveView();
nIndex = (int) DialogSaveAs.m_ofn.nFilterIndex;
if( nIndex == 5 )
{
if( m_pImageObject->GetNumBits() != 24 )
{
AfxMessageBox("必须是24位真彩色图像才能存为JPEG格式!");
return;
}
}
if( m_pImageObject != NULL )
{
CString strPathName = DialogSaveAs.GetPathName();
int nFindIndex = strPathName.Find(".");
if( nFindIndex != -1)
strPathName = strPathName.Left( nFindIndex );
strPathName += CImageObject::szExtensions[ nIndex - 1 ];
m_pImageObject->Save( strPathName );
CString strFileName = DialogSaveAs.GetFileName();
nFindIndex = strFileName.Find(".");
if ( nFindIndex != -1 )
strFileName = strFileName.Left( nFindIndex );
strFileName += CImageObject::szExtensions[ nIndex - 1 ];
pChildFrame->SetWindowText( strFileName );
SetPathName( strPathName );
if( nIndex == 5 )
{
m_pImageObject->Load( strPathName );
pDipView->InvalidateRect( NULL, FALSE );
pDipView->UpdateWindow();
}
}
}
}
BOOL CDipDoc::LoadImageToDocument()
{
CString strPathName = GetPathName();
//设置等待光标
BeginWaitCursor();
m_pImageObject = new CImageObject( strPathName.GetBuffer(3) );
//取消等待光标
EndWaitCursor();
//读入图像文件失败
if( m_pImageObject == NULL )
{
AfxMessageBox("无法创建图像类对象!");
//返回FALSE
return(FALSE);
}
//读入图像文件成功,设置相应变量
m_bImageLoaded = TRUE;
//返回TRUE
return(TRUE);
}
void CDipDoc::OnFileNew()
{
// TODO: Add your command handler code here
}
void CDipDoc::OnBmpinfo()
{
// TODO: Add your command handler code here
CBmpFileInfo bmpFile1;
bmpFile1.m_nFileSize=m_pImageObject->GetFileSize();
bmpFile1.m_biBitCount=m_pImageObject->GetNumBits();
bmpFile1.m_biHeight=m_pImageObject->GetHeight();
bmpFile1.m_biWidth=m_pImageObject->GetWidth();
bmpFile1.DoModal();
}
BOOL CDipDoc::OnZhifangtu()
{
// TODO: Add your command handler code here
//若未指定m_pImageObject对象指针返回FALSE
if(m_pImageObject== NULL ) return( FALSE );
//只处理8位图像
if(m_pImageObject->GetNumBits() != 8)
{
AfxMessageBox("目前只支持8位灰度图像的处理!");
return( FALSE );
}
//定义变量
unsigned char *pBuffer, *pBits, *pTemp;
BITMAPINFOHEADER *pBIH;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors, x, y;
int nWidth = m_pImageObject->GetWidth();
int nHeight = m_pImageObject->GetHeight();
//pBuffer: 获得位图数据指针
pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes,
m_pImageObject->GetNumBits() );
if( pBuffer == NULL ) return( FALSE );
//pBIH:获得位图信息头地址
pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
//nNumColors:获得调色板中的颜色数。图像为16位色或更高时为0
nNumColors = m_pImageObject->GetNumColors();
//pPalette:获得调色板数据地址
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//pBits:获得位图数据地址
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
nNumColors*sizeof(RGBQUAD)];
// 创建直方图数据
int *pHistogram = GetHistogram();
// 灰度映射表
BYTE bMap[256];
int i, j;
for(i = 0; i < 256; i++)
{
bMap[i] = 0;
}
// 计算灰度映射表
for (i = 0; i < 256; i++)
{
// 初始为0
long lTemp = 0;
for (j = 0; j <= i ; j++)
{
lTemp += pHistogram[j];
}
// 计算对应的新灰度值
bMap[i] = (BYTE) (lTemp*255/nHeight/nWidth);
}
delete [] pHistogram;
for(y = 0; y < nHeight; y++)
{
pTemp = pBits;
pTemp += y * nWidthBytes; //位图数据下一行起始指针
for(x = 0; x < nWidth; x++)
{
long lpSrc = pTemp[x];
// 计算新的灰度值
pTemp[x] = bMap[lpSrc];
}
}
::GlobalUnlock(m_pImageObject->GetDib());
BeginWaitCursor();
UpdateAllViews(NULL);
EndWaitCursor();
return TRUE;
}
int *CDipDoc::GetHistogram(int nX1,int nY1,int nX2, int nY2,CImageObject *pDibObject)
{
//使用传入的CDibObject对象
if( pDibObject != NULL ) m_pImageObject = pDibObject;
//无CDibObject对象, 返回FALSE
if( m_pImageObject == NULL ) return( FALSE );
//坐标规整化
m_pImageObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
//定义变量
unsigned char *pBuffer, *pBits;
RGBQUAD *pPalette;
int nWidthBytes, nNumColors;
//获得图像指针
pBuffer = (unsigned char *) m_pImageObject->GetDIBPointer( &nWidthBytes, m_pImageObject->GetNumBits() );
if( pBuffer == NULL ) return( NULL );
//获得颜色数
nNumColors = m_pImageObject->GetNumColors();
//获得调色板指针
pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//获得位图数据指针
pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
//创建直方图数据
int *nHistogramBuffer = CreateHistogram( nX1, nY1, nX2, nY2, pBits, pPalette, nWidthBytes );
::GlobalUnlock( m_pImageObject->GetDib() );
return( nHistogramBuffer );
}
int *CDipDoc::CreateHistogram(int nX1,int nY1,int nX2,int nY2,
unsigned char *pData, RGBQUAD *pPalette,
int nWidthBytes, CImageObject *pDibObject )
{
//图像指针为空,无法操作返回
if( pDibObject != NULL )m_pImageObject= pDibObject;
if( m_pImageObject== NULL ) return( FALSE );
//分配直方图数据缓存区(数组)
int *pBuffer = new int [256 * 4];
//分配直方图数据缓存区失败
if( pBuffer == NULL ) return( NULL );
//直方图数据缓存区清零
memset( pBuffer, 0, ( 256 * 4) * sizeof( int ) );
//变量定义
DWORD dwGray;
int x, y;
unsigned char *pTemp, ucRed, ucGreen, ucBlue;
//图像的高度
int nHeight =m_pImageObject->GetHeight();
switch(m_pImageObject->GetNumBits() )
{
case 1: //每像素位数为1,不处理
break;
case 4: //每像素位数为4,不处理
break;
case 8: //每像素位数为8
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += nX1;
for( x = nX1; x <= nX2; x++ )
{
//pTemp[x]为当前像素值,它为调色板项的索引值,
//以此为索引,取出调色板项的相应红绿蓝分量值。
ucRed = pPalette[pTemp[x]].rgbRed;
ucGreen = pPalette[pTemp[x]].rgbGreen;
ucBlue = pPalette[pTemp[x]].rgbBlue;
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
}
}
break;
case 16: //每像素位数为16
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 2 );
for( x = nX1; x <= nX2; x++ )
{
//获取三原色分量
GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
//数据指针加2
pTemp += 2;
}
}
break;
case 24: //每像素位数为24
for( y = nY1; y < nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 3 );
for( x=nX1; x<=nX2; x++ )
{
//获取像素颜色的三原色。
ucRed = pTemp[x * 3 + 2];
ucGreen = pTemp[x * 3 + 1];
ucBlue = pTemp[x * 3];
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
//数据指针加3
pTemp += 3;
}
}
break;
case 32: //每像素位数为24
for( y = nY1; y <= nY2; y++ )
{
//数据指针定位到图像数据起始位置
pTemp = pData;
//数据指针定位到图像数据每行的起始零位置
pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
//数据指针定位到图像数据每行的起始nX1位置
pTemp += ( nX1 * 4 );
for( x = nX1; x <= nX2; x++ )
{
//获取像素颜色的三原色。
GETRGB888( ucRed, ucGreen, ucBlue, pTemp );
//按关系L=0.3R+0.59G+0.11B,得到亮度值
dwGray = ( (DWORD) ucRed * 30 +
(DWORD) ucGreen * 59 +
(DWORD) ucBlue * 11 ) / 100;
dwGray &= 0x000000ff;
//亮度直方图数据
pBuffer[dwGray]++;
//红色直方图数据
pBuffer[256 + ucRed]++;
//绿色直方图数据
pBuffer[512 + ucGreen]++;
//蓝色直方图数据
pBuffer[768 + ucBlue]++;
pTemp += 4;
}
}
break;
}
return( pBuffer );
}