📄 bitmapfile.cpp
字号:
#include "stdafx.h"
#include "BitmapFile.h"
#include <memory.h>
IMPLEMENT_DYNAMIC(CBitmapFile,CGdiObject);
CBitmapFile* PASCAL CBitmapFile::FromHandle(HBITMAP hBitmap)
{
return (CBitmapFile*) CGdiObject::FromHandle(hBitmap);
}
CBitmapFile::CBitmapFile()
{
m_nWidth = 400;
m_nHeight = 400;
m_iPixel = 24;
m_nBitLen = (m_nWidth*m_nHeight*m_iPixel)/8;
m_memDC = NULL;
m_pBmpInfo = NULL;
m_pCreateBmpInfo = NULL;
m_pBmpBits = NULL;
m_pSavedBmpBits = NULL;
CreateBitmap(m_nWidth, m_nHeight, m_iPixel, NULL);
}
BOOL CBitmapFile::LoadBitmap(LPCTSTR lpszFileName)
{
CFile file;
if(!file.Open(lpszFileName,CFile::modeRead|CFile::shareDenyWrite))
{
MessageBox(NULL,"BMP file open error!","warning",MB_OK);
return FALSE;
}
try
{
file.Read(&m_BmpFileHead,sizeof(BITMAPFILEHEADER));
if(m_BmpFileHead.bfType!=((WORD) ('M'<<8)|'B'))
{
MessageBox(NULL,"The file is not a BMP file!","warning",MB_OK);
return FALSE;
}
if(m_BmpFileHead.bfSize!=file.GetLength())
{
// MessageBox(NULL,"The BMP file header error!","warning",MB_OK);
// return FALSE;
}
UINT uBmpInfoLen = (UINT) m_BmpFileHead.bfOffBits-sizeof(BITMAPFILEHEADER);
m_pBmpInfo = (LPBITMAPINFO) new BYTE[uBmpInfoLen];
file.Read((LPVOID) m_pBmpInfo,uBmpInfoLen);
m_nWidth = m_pBmpInfo->bmiHeader.biWidth;
m_nHeight = m_pBmpInfo->bmiHeader.biHeight;
if((* (LPDWORD)(m_pBmpInfo))!=sizeof(BITMAPINFOHEADER))
{
MessageBox(NULL,"The BMP is not Windows 3.0 format!","warning",MB_OK);
return FALSE;
}
m_nBitLen = m_BmpFileHead.bfSize - m_BmpFileHead.bfOffBits;
m_pBmpBits=new BYTE[m_nBitLen];
file.ReadHuge(m_pBmpBits,m_nBitLen);
file.Close();
}
catch(CFileException e)
{
AfxMessageBox("Open Failed!");
return FALSE;
}
BOOL bSuccess=CreateBitmapIndirect(m_pBmpInfo, m_pBmpBits);
if(!bSuccess)
return FALSE;
return TRUE;
}
BOOL CBitmapFile::SaveBitmap(LPCTSTR lpszFileName)
{
LPBITMAPINFO CurrentSavedBmp;
if(!m_pBmpInfo)
{
ZeroMemory(&m_BmpFileHead, sizeof(BITMAPFILEHEADER));
*((char *)&m_BmpFileHead.bfType) = 'B';
*(((char *)&m_BmpFileHead.bfType) + 1) = 'M';
m_BmpFileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
m_BmpFileHead.bfSize = m_nBitLen;
CurrentSavedBmp = m_pCreateBmpInfo;
}
else
{
CurrentSavedBmp = m_pBmpInfo;
m_pBmpBits = m_pSavedBmpBits;
}
CFile file;
if(file.Open(lpszFileName, CFile::modeWrite | CFile::modeCreate))
{
try
{
file.Write(&m_BmpFileHead,sizeof(BITMAPFILEHEADER));
file.Write(&(CurrentSavedBmp->bmiHeader),sizeof(BITMAPINFOHEADER));
file.WriteHuge(m_pBmpBits,m_nBitLen);
file.Flush( );
file.Close();
}
catch(CFileException e)
{
AfxMessageBox("Save File Failed!");
return FALSE;
}
}
else
{
AfxMessageBox("Save Failed!");
return FALSE;
}
return TRUE;
}
BOOL CBitmapFile::CreateBitmap(int nWidth, int nHeight, UINT nBitCount,
const void* lpSrcBits)
{
ASSERT(nBitCount==1||nBitCount==4||nBitCount==8
||nBitCount==16||nBitCount==24||nBitCount==32);
m_pCreateBmpInfo=(BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) +
GetColorNumber(nBitCount) * sizeof(RGBQUAD)];
m_pCreateBmpInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_pCreateBmpInfo->bmiHeader.biWidth=nWidth;
m_pCreateBmpInfo->bmiHeader.biHeight=nHeight;
m_pCreateBmpInfo->bmiHeader.biBitCount=nBitCount;
m_pCreateBmpInfo->bmiHeader.biPlanes=1;
m_pCreateBmpInfo->bmiHeader.biCompression=BI_RGB;
m_pCreateBmpInfo->bmiHeader.biSizeImage=0;
m_pCreateBmpInfo->bmiHeader.biClrUsed=0;
m_pCreateBmpInfo->bmiHeader.biClrImportant = 0;
BOOL bSuccess=CreateBitmapIndirect(m_pCreateBmpInfo, lpSrcBits);
if(!bSuccess)
return FALSE;
return TRUE;
}
BOOL CBitmapFile::CreateBitmapIndirect(LPBITMAPINFO lpBitmapInfo, const void* lpSrcBits)
{
DeleteObject();
LPVOID lpBits;
m_memDC = new CDC;
m_memDC->CreateCompatibleDC(NULL);
HBITMAP hBitmap=::CreateDIBSection(m_memDC->m_hDC,lpBitmapInfo,DIB_RGB_COLORS,
&lpBits,NULL,0);
ASSERT(hBitmap!=NULL);
Attach(hBitmap);
BITMAP bmp;
GetBitmap(&bmp);
DWORD dwCount=(DWORD) bmp.bmWidthBytes * bmp.bmHeight;
if(!lpSrcBits)
{
m_pBmpBits = lpBits;
m_memDC->SelectObject(this);
m_memDC->SetBkMode(TRANSPARENT);
CRect rcClient(0, 0, m_nWidth, m_nHeight);
CPen penCtl;
penCtl.CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
CPen *pOldPen = m_memDC->SelectObject(&penCtl);
m_memDC->Rectangle(rcClient);
m_memDC->SelectObject(pOldPen);
m_memDC->DeleteDC();
return TRUE;
}
m_pSavedBmpBits = lpBits;
if(SetBitmapBits(dwCount,lpSrcBits)!=dwCount)
{
MessageBox(NULL,"DIB build error!","warning",MB_OK);
return FALSE;
}
return TRUE;
}
CBitmapFile::operator HBITMAP() const
{
return (HBITMAP)(this == NULL ? NULL : m_hObject);
}
int CBitmapFile::GetBitmap(BITMAP* pBitMap)
{
ASSERT(m_hObject != NULL);
return ::GetObject(m_hObject, sizeof(BITMAP), pBitMap);
}
// helper functions
int CBitmapFile::GetColorNumber(WORD wBitCount)
{
ASSERT(wBitCount==1||wBitCount==4||wBitCount==8
||wBitCount==16||wBitCount==24||wBitCount==32);
switch(wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
DWORD CBitmapFile::SetBitmapBits(DWORD dwCount, const void* lpBits)
{
if(lpBits!=NULL)
{
BITMAP bmp;
GetBitmap(&bmp);
memcpy(bmp.bmBits,lpBits,dwCount);
return dwCount;
}
else
return 0;
}
DWORD CBitmapFile::GetBitmapBits(DWORD dwCount, LPVOID lpBits)
{
if(lpBits!=NULL)
{
BITMAP bmp;
GetBitmap(&bmp);
memcpy(lpBits,bmp.bmBits,dwCount);
return dwCount;
}
else
return 0;
}
CBitmapFile::~CBitmapFile()
{
delete m_pCreateBmpInfo;
m_pCreateBmpInfo = NULL;
delete m_pBmpInfo;
m_pBmpInfo = NULL;
// delete m_pBmpBits;
m_pBmpBits = NULL;
delete m_memDC;
m_memDC = NULL;
CGdiObject::DeleteObject();
}
UINT CBitmapFile::GetWidth()
{
return m_nWidth;
}
UINT CBitmapFile::GetHeight()
{
return m_nHeight;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -