graphdib.cpp
来自「读写位图文件的」· C++ 代码 · 共 275 行
CPP
275 行
// GraphDIB.cpp: implementation of the CGraphDIB class.
// 作者:董希华
// 日期:2004年11月05日
// 联系方式: sddongxh@hotmail.com
// 说明:本例程曾参考多人的代码,在此致谢!
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "myDib.h"
#include "GraphDIB.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define PALVERSION 0x300
IMPLEMENT_SERIAL(CGraphDIB,CObject,1)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGraphDIB::CGraphDIB()
{
m_hBmp = NULL;
m_pBmpInfo = NULL;
m_pPixels = NULL;
}
CGraphDIB::~CGraphDIB()
{
//m_pPixels在GDI对象m_hBmp被销毁时同时释放
if(m_hBmp!=NULL)
{
DeleteObject(m_hBmp);
m_hBmp = NULL;
m_pPixels = NULL;
}
if(m_pBmpInfo!=NULL)
{
delete []m_pBmpInfo;
}
}
bool CGraphDIB::LoadBmp(CFile &file)
{
DWORD dwStart = file.GetPosition();
BITMAPFILEHEADER bfhHeader;
file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));
if(bfhHeader.bfType!=((WORD)('M'<<8)|'B')) //判断是否是bmp文件
{
AfxMessageBox("文件不是bmp文件");
return false;
}
if(bfhHeader.bfSize!=file.GetLength())
{
AfxMessageBox("文件已经损坏!");
return false;
}
int nBmpInfoLen = bfhHeader.bfOffBits - sizeof(BITMAPFILEHEADER);//判断位图信息头的长度
m_pBmpInfo = (LPBITMAPINFO)new BYTE[nBmpInfoLen]; //创建信息头
file.Read((void*)m_pBmpInfo,nBmpInfoLen); //读入位图信息
UINT nBitLen = bfhHeader.bfSize - bfhHeader.bfOffBits; //位图象素数据的长度
m_hBmp = ::CreateDIBSection(NULL,m_pBmpInfo,DIB_RGB_COLORS,(void**)&m_pPixels,NULL,0);
if(m_hBmp==NULL)
{
delete []m_pBmpInfo;
m_pBmpInfo = NULL;
return false;
}
// file.Seek(dwStart + bfhHeader.bfOffBits,CFile::begin);
if(file.ReadHuge(m_pPixels,nBitLen)!=nBitLen)
{
AfxMessageBox("读文件时发生错误!");
file.Close();
delete []m_pBmpInfo;
m_pBmpInfo = NULL;
DeleteObject(m_hBmp);
m_hBmp = NULL;
return false;
}
m_rectBound = CRect(0,0,Width(),Height());
int nSize = file.GetPosition();
return true;
}
bool CGraphDIB::LoadBmp(const char *lpszFileName)
{
//如果已经创建了对象,安全清除之
if(m_hBmp!=NULL)
{
DeleteObject(m_hBmp);
m_hBmp = NULL;
m_pPixels = NULL;
}
if(m_pBmpInfo!=NULL)
{
delete []m_pBmpInfo;
}
//
CFile file;
if(!file.Open(lpszFileName,CFile::modeRead|CFile::shareDenyWrite))
{
AfxMessageBox("未能打开bmp文件!");
return false;
}
bool res = LoadBmp(file);
file.Close();
return res;
}
int CGraphDIB::Width() const
{
if(m_pBmpInfo!=NULL)
return m_pBmpInfo->bmiHeader.biWidth;
else
return 0;
}
int CGraphDIB::Height() const
{
if(m_pBmpInfo!=NULL)
return m_pBmpInfo->bmiHeader.biHeight;
else
return 0;
}
void CGraphDIB::Serialize(CArchive &ar)
{
if(ar.IsStoring())
{
CFile *pFile = ar.GetFile();
ar.Flush();
WriteToFile(*pFile);
}
else
{
CFile *pFile = ar.GetFile();
ar.Flush();
bool res = LoadBmp(*pFile);
}
}
int CGraphDIB::GetBmpInfoSize() const //获取位图信息头的大小
{
if(m_pBmpInfo==NULL)
return 0;
int nbitCount = m_pBmpInfo->bmiHeader.biBitCount;
int nPalEntries = 0;
if(nbitCount<=8)
nPalEntries = 1<<nbitCount;
return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nPalEntries;
}
bool CGraphDIB::WriteToFile(CFile &file)
{
if(m_hBmp==NULL)
return false;
BITMAPFILEHEADER bfhHeader;
bfhHeader.bfType = 0x4d42; // 'BM'
bfhHeader.bfSize = sizeof(BITMAPFILEHEADER) + GetBmpInfoSize() + GetBmpDataSize();
bfhHeader.bfReserved1 = 0;
bfhHeader.bfReserved2 = 0;
bfhHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + GetBmpInfoSize();
file.Write((void*)&bfhHeader,sizeof(BITMAPFILEHEADER));
file.Write((void*)m_pBmpInfo,GetBmpInfoSize());
file.WriteHuge((void*)m_pPixels,GetBmpDataSize());
return true;
}
int CGraphDIB::GetBmpDataSize() const
{
if(m_hBmp != NULL)
{
BITMAP bmp;
::GetObject(m_hBmp,sizeof(BITMAP),&bmp);
return bmp.bmWidthBytes*bmp.bmHeight;
}
else
return 0;
}
CGraphDIB::CGraphDIB(const CGraphDIB &s)
{
if(s.m_hBmp==NULL)
{
m_hBmp = NULL;
m_pBmpInfo = NULL;
m_pPixels = NULL;
return;
}
int nBmpInfoLen = s.GetBmpInfoSize();
m_pBmpInfo = (LPBITMAPINFO)new BYTE[nBmpInfoLen]; //创建信息头
memcpy(m_pBmpInfo,s.m_pBmpInfo,nBmpInfoLen);
m_hBmp = CreateDIBSection(NULL,m_pBmpInfo,DIB_RGB_COLORS,(void**)&m_pPixels,NULL,0);
memcpy(m_pPixels,s.m_pPixels,s.GetBmpDataSize());
m_rectBound = s.m_rectBound;
}
int CGraphDIB::GetPalEntries()
{
if(m_pBmpInfo==NULL)
return 0;
int dwClrUsed = m_pBmpInfo->bmiHeader.biClrUsed;
if (dwClrUsed != 0)
return (WORD)dwClrUsed;
int nbitCount = m_pBmpInfo->bmiHeader.biBitCount;
int nPalEntries = 0;
if(nbitCount<=8)
nPalEntries = 1<<nbitCount;
return nPalEntries;
}
void CGraphDIB::Draw(CDC *pDC)
{
if(m_hBmp == NULL)
return;
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
HBITMAP hbmp = (HBITMAP)dcMem.SelectObject(m_hBmp);
int nHeight = Height();
int nWidth = Width();
CRect rect = m_rectBound;
pDC->StretchBlt(m_rectBound.left,m_rectBound.top,m_rectBound.Width(),m_rectBound.Height(),&dcMem,0,0,nWidth,nHeight,SRCCOPY);
dcMem.SelectObject(hbmp);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?