📄 dipdoc.cpp
字号:
// dipDoc.cpp : implementation of the CDipDoc class
//
#include "stdafx.h"
#include "dip.h"
#include "afx.h"
#include "dipDoc.h"
#include "GreyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDipDoc
IMPLEMENT_DYNCREATE(CDipDoc, CDocument)
BEGIN_MESSAGE_MAP(CDipDoc, CDocument)
//{{AFX_MSG_MAP(CDipDoc)
ON_COMMAND(ID_grey, Ongrey)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDipDoc construction/destruction
CDipDoc::CDipDoc()
{
// TODO: add one-time construction code here
//初始化图像数据和调色板
ImgWidth=0;
ImgHeight=0;
ImgData=NULL;
palette=NULL;
}
CDipDoc::~CDipDoc()
{
//释放所分配的空间
if (ImgData) delete []ImgData;
if (palette) delete []palette;
}
BOOL CDipDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// 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
//打开文件名为filename的文件,并从中读取信息
void CDipDoc::FileOpen(CString filename)
{
CString promt;//提示字符串
int flag=true;//标志是否成功的打开文件
CFile fp; //新建一个文件
BYTE num[4];
//打开文件
fp.Open(filename,CFile::modeRead|CFile::typeBinary);
if (fp==NULL)
{
promt="Can't Open file "+filename;
AfxMessageBox(promt);
flag=false;
}
//保存图像信息
fp.Read(header,14); //位图文件头
fp.Read(infoheader,40);
//位图信息头
//读取biClrUsed色彩数目
fp.Seek(46,CFile::begin);
fp.Read(num,4);
colorused=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
//如果biClrUsed为0,则读取biBitCount像素位数目
if (!colorused)
{
fp.Seek(28,CFile::begin);
fp.Read(num,2);
colorused=(num[1]<<8)|num[0];
colorused=1<<colorused; //色彩数目为2的像素位数目次方
}
//删除原有调色板
if (palette) delete []palette;
palette=new RGBQUAD[colorused];
//读取新调色板
fp.Seek(54,CFile::begin);
fp.Read(palette,colorused*sizeof(palette));
//判断是否是BMP图像
WORD ImgType;
fp.SeekToBegin();
fp.Read(&ImgType,1);
if (ImgType!=((('M'+127)*256)+'B'))
{
promt="file "+filename+" is not a BMP file";
AfxMessageBox(promt);
flag=false;
}
//判断是否是256色位图
BYTE ImgBitCount;
fp.Seek(28,CFile::begin);
fp.Read(&ImgBitCount,1);
if (ImgBitCount!=8)
{
promt="file "+filename+" is not a Greyscale";
AfxMessageBox(promt);
flag=false;
}
//符合条件,则读取文件信息
if (flag)
{
//更新文件名信息
FileName=filename;
//读取图像的宽度和高度
fp.Seek(18,CFile::begin);
fp.Read(num,4);
ImgWidth=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
fp.Read(num,4);
ImgHeight=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
//删除原有的数据区,并根据图像大小重新分配数据区
if (ImgData) delete [] ImgData;
ImgData=new BYTE[ImgWidth*ImgHeight];
//读区数据区开始的偏移量
LONG offset;
fp.Seek(10,CFile::begin);
fp.Read(num,4);
offset=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
fp.Seek(offset,CFile::begin);
//每次读取一行的像素点,并删除添加的冗余点
int i;
int temp=ImgWidth%4;
if (temp) temp=4-temp;
//注意,是从下往上,从左往右来
for(i=0;i<ImgHeight;i++)
{
fp.Read(ImgData+(ImgHeight-i-1)*ImgWidth,ImgWidth);
fp.Seek(temp,CFile::current);
}
}
fp.Close(); //读取结束,关闭文件
}
//计算图像的灰度直方图
void CDipDoc::Ongrey()
{
// TODO: Add your command handler code here
int i;
CGreyDlg greyDlg;
for(i=0;i<ImgWidth*ImgHeight;i++)
greyDlg.grey[ImgData[i]]++; //统计灰度信息
greyDlg.DoModal(); //显示灰度直方图对话框
}
//将现有的图像存入文件filename中
int CDipDoc::FileSave(CString filename)
{
CFile fp;
//打开文件
fp.Open(filename,CFile::modeWrite|CFile::typeBinary|CFile::modeCreate);
if (!fp)
{
AfxMessageBox("Write error!");
return(0); //出错返回
}
//写入原图像的头部信息
fp.Write(header,14);
fp.Write(infoheader,40);
fp.Write(palette,colorused*4);
//写入当前图像的数据信息
int i;
char c[4]={0,0,0,0};
int temp=ImgWidth%4;
if (temp) temp=4-temp;
for(i=0;i<ImgHeight;i++)
{
fp.Write(ImgData+(ImgHeight-i-1)*ImgWidth,ImgWidth);
if (temp)
fp.Write(c,temp); //添加冗余字段
}
//更新图像的大小信息
DWORD length;
BYTE temp1;
fp.Seek(2,CFile::begin); //更新bfSize文件大小
length=fp.GetLength();
for(i=0;i<4;i++)
{
temp1=(BYTE)length%256;
length=length/256;
fp.Write(&temp1,1);
}
fp.Seek(18,CFile::begin); //更新biWidth图像宽度
length=ImgWidth;
for(i=0;i<4;i++)
{
temp1=(BYTE)length%256;
length=length/256;
fp.Write(&temp1,1);
}
fp.Seek(22,CFile::begin); //更新biHeight图像高度
length=ImgHeight;
for(i=0;i<4;i++)
{
temp1=(BYTE)length%256;
length=length/256;
fp.Write(&temp1,1);
}
fp.Close(); //关闭文件
return(1);
}
//重新打开默认的文件,并从中读取图像信息
void CDipDoc::FileOpen()
{
CString promt;//提示字符串
int flag=true;//标志是否成功的打开文件
CFile fp;
//打开文件
fp.Open(FileName,CFile::modeRead|CFile::typeBinary);
if (fp==NULL)
{
promt="Can't Open file "+FileName;
AfxMessageBox(promt);
flag=false;
}
//如果打开成功
if (flag)
{
BYTE num[4];
//读取图像的宽度和高度
fp.Seek(18,CFile::begin);
fp.Read(num,4);
ImgWidth=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
fp.Read(num,4);
ImgHeight=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
//删除原有的数据区,并根据图像大小重新分配数据区
if (ImgData) delete [] ImgData;
ImgData=new BYTE[ImgWidth*ImgHeight];
//读区数据区开始的偏移量
LONG offset;
fp.Seek(10,CFile::begin);
fp.Read(num,4);
offset=(num[3]<<24)|(num[2]<<16)|(num[1]<<8)|num[0];
fp.Seek(offset,CFile::begin);
//每次读取一行的像素点,并删除添加的冗余点
int i;
int temp=ImgWidth%4;
if (temp) temp=4-temp;
for(i=0;i<ImgHeight;i++)
{
fp.Read(ImgData+(ImgHeight-i-1)*ImgWidth,ImgWidth);
fp.Seek(temp,CFile::current);
}
}
fp.Close();//读取结束关闭文件
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -