// BmpImage.h: interface for the BmpImage class.
//
//
#if !defined(AFX_BMPIMAGE_H__E53F79EE_E96D_4B6B_88BC_F79EF1B1CE11__INCLUDED_)
#define AFX_BMPIMAGE_H__E53F79EE_E96D_4B6B_88BC_F79EF1B1CE11__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class BmpImage : public CObject
{
public:
DWORD GetBytesPerPix();
DWORD GetBitsPerPix();
DWORD GetNumOfColorTab();
void Display(CDC* pDC);
BmpImage();
BmpImage(CFile *BmpFile);
BmpImage(CString FileName);
DWORD GetSize();
DWORD GetWidth();
DWORD GetHeight();
BYTE* GetData();
DWORD GetBmpWidthBytes();
BITMAPINFO* GetBmpInfo();
DWORD LoadFile();
void Display( HDC hdc);
virtual ~BmpImage();
private:
DWORD m_NumOfColorTab;
DWORD m_NumOfColors;
RGBQUAD* m_pRGBTAB;
BYTE* m_pData;//所读图像文件的数据指针
BOOL m_Valid;//标识所读取的文件是否合法
CString m_FileName;
BITMAPFILEHEADER m_BmpFileHeader;
BITMAPINFOHEADER* m_pBmpInfoHeader;
BITMAPINFO* m_pBmpInfo;
CFile *BmpFile;
};
#endif // !defined(AFX_BMPIMAGE_H__E53F79EE_E96D_4B6B_88BC_F79EF1B1CE11__INCLUDED_)
// BmpImage.cpp: implementation of the BmpImage class.
//
//
#include "stdafx.h"
#include "BiShe.h"
#include "BmpImage.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
BmpImage::BmpImage()
{
}
BmpImage::BmpImage(CFile *BmpFile)
{
this->BmpFile=BmpFile;
LoadFile();
}
BmpImage::~BmpImage()
{
free(m_pData);
}
BmpImage::BmpImage(CString filename)
{
this->m_FileName=filename;
BmpFile=new CFile(m_FileName, CFile::modeRead);
LoadFile();
}
/**********************************************************
函数名:Display
功能:简单的显示图像
入口参数:pDC
出口参数:无
说明:仅用于图像的简单快速显示
**********************************************************/
void BmpImage::Display(CDC *pDC)
{
CBitmap m_bitmap;
HBITMAP hBitmap=(HBITMAP)LoadImage(NULL,_T(m_FileName),IMAGE_BITMAP,
0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);
if(!hBitmap)return;
m_bitmap.Attach (hBitmap);
CDC dcImage;
if(!dcImage.CreateCompatibleDC(pDC))
return;
BITMAP bm;
m_bitmap.GetBitmap (&bm);
dcImage.SelectObject (&m_bitmap);
pDC->BitBlt (0,0,bm.bmWidth ,bm.bmHeight ,&dcImage,0,0,SRCCOPY);
}
/**********************************************************
函数名:Display
功能:显示图像
入口参数:hdc:设备句柄
出口参数:无
说明:与上不同,它主要用于对处理后的图像的数据的显示
**********************************************************/
void BmpImage::Display( HDC hdc)
{
StretchDIBits(hdc,0,0,GetWidth(),GetHeight(),0,0,GetWidth(),
GetHeight(),m_pData,m_pBmpInfo,NULL,MERGECOPY);
}
/**********************************************************
函数名:LoadFile
功能:获取图像的各种数据结构和数据
入口参数:无
出口参数:无
说明:该函数必须在所有其它成员函数之前被调用,否则将出现不可
预料的结果,此函数并不进行图像的显示
**********************************************************/
DWORD BmpImage::LoadFile()
{
BmpFile->Read((void*)&m_BmpFileHeader,sizeof(BITMAPFILEHEADER));
if (m_BmpFileHeader.bfType == 0x4d42)
{
DWORD fileLength = BmpFile->GetLength();
DWORD size = fileLength - sizeof(BITMAPFILEHEADER);
BYTE* pBmpBuf =(BYTE*)malloc(size);
if(!pBmpBuf)
return 1;
BmpFile->Read((void*)pBmpBuf, size);
//BmpFile->Close();
//获取文件信息指针
m_pBmpInfo = (BITMAPINFO*) pBmpBuf;
//获取文件信息头指针
m_pBmpInfoHeader = (BITMAPINFOHEADER*) pBmpBuf;
//获取调色板指针
m_pRGBTAB = (RGBQUAD*)(pBmpBuf + m_pBmpInfoHeader->biSize);
int m_NumOfColorTab = GetNumOfColorTab();
if (m_pBmpInfoHeader->biClrUsed == 0)
m_pBmpInfoHeader->biClrUsed =m_NumOfColorTab;
//获取彩色表的尺寸
DWORD ColorTableSize = m_NumOfColorTab *sizeof(RGBQUAD);
m_pData = pBmpBuf + m_pBmpInfoHeader->biSize
+ ColorTableSize;
if (m_pRGBTAB == (RGBQUAD*)m_pData) // No color table
m_pRGBTAB = NULL;
m_pBmpInfoHeader->biSizeImage = GetSize();
m_Valid = TRUE;
}
else
{
m_Valid = FALSE;
AfxMessageBox("This isn't a bitmap file!");
}
return 0;
}
/**********************************************************
函数名:GetNumOfColorTab
功能:获取图像的调色板项数
入口参数:无
出口参数:调色板项数
说明:调色板的每项用四个字节表示,第四字节保留,前三字节分别为
黄绿蓝三颜色的值,一般而言16/24位图像无调色板
**********************************************************/
DWORD BmpImage::GetNumOfColorTab()
{
if ((m_pBmpInfoHeader->biClrUsed == 0)&&(m_pBmpInfoHeader->biBitCount<9))
{
switch (m_pBmpInfoHeader->biBitCount)
{
case 1: m_NumOfColorTab = 2; break;
case 4: m_NumOfColorTab = 16; break;
case 8: m_NumOfColorTab = 256;break;
}
}
else
m_NumOfColorTab = (DWORD) m_pBmpInfoHeader->biClrUsed;
return m_NumOfColorTab;
}
/**********************************************************
函数名:GetSize
功能:获取图像的面积
入口参数:无
出口参数:图像面积
说明:图像的面积为其高*宽,单位为/像数点
**********************************************************/
DWORD BmpImage::GetSize()
{
if (m_pBmpInfoHeader->biSizeImage != 0)
return m_pBmpInfoHeader->biSizeImage;
else
{
DWORD height = (DWORD) GetHeight();
DWORD width = (DWORD) GetWidth();
return height * width;
}
}
/**********************************************************
函数名:GetWidth
功能:获取图像宽度
入口参数:无
出口参数:图像宽度
说明:图像宽度的单位为/像数点
**********************************************************/
DWORD BmpImage::GetWidth()
{
return (UINT) m_pBmpInfoHeader->biWidth;
}
/**********************************************************
函数名:GetHeight
功能:获取图像高度
入口参数:无
出口参数:图像高度
说明:图像高度的单位为/像数点
**********************************************************/
DWORD BmpImage::GetHeight()
{
return (UINT) m_pBmpInfoHeader->biHeight;
}
/**********************************************************
函数名:GetData
功能:获取图像的数据指针
入口参数:无
出口参数:m_pData:图像在内存中的数据的开始地址
说明:图像数据是指专门用于显示的数据,而非为组织其它数据服务的数据结构
**********************************************************/
BYTE* BmpImage::GetData()
{
return m_pData;
}
/**********************************************************
函数名:GetBmpWidthBytes
功能:获取图像每一行占用的字节数
入口参数:无
出口参数:图像每一行占用的字节数
说明:图像每行占用的字节数必须为4的整数倍
**********************************************************/
DWORD BmpImage::GetBmpWidthBytes()
{
//DWORD dwWidth=m_pBitmapInfoHeader->biWidth;
//DWORD dwWidthBytes;
/*switch(m_pBmpInfoHeader->biBitCount)
{
case 1: dwWidthBytes = (nWidth + 7) / 8;
case 4: dwWidthBytes = (nWidth + 1) / 2;
case 8: dwWidthBytes = (nWidth + 1) / 2;
case:(byBitCount == 24) dwWidthBytes = 3 * nWidth ;
}
while((dwWidthBytes & 3) != 0)dwWidthBytes++;*/
return ((m_pBmpInfoHeader->biBitCount*m_pBmpInfoHeader->biWidth+31)>>5)<<2;
}
/**********************************************************
函数名:GetBmpInfo
功能:获取位图信息头指针
入口参数:无
出口参数:位图信息头指针
说明:位图信息头用于描述位图文件的大小,压缩方式,图像宽和高度等
**********************************************************/
BITMAPINFO* BmpImage::GetBmpInfo()
{
return m_pBmpInfo;
}
/**********************************************************
函数名:GetBitsPerPix
功能:获取位图图像的颜色位数
入口参数:无
出口参数:m_NumOfColors:位图信息头指针
说明:位图图像的颜色位数是指表示每个像素点所用的二进制位数
**********************************************************/
DWORD BmpImage::GetBitsPerPix()
{
if ((m_pBmpInfoHeader->biClrUsed == 0)&&(m_pBmpInfoHeader->biBitCount<9))
{
switch (m_pBmpInfoHeader->biBitCount)
{
case 1: m_NumOfColors = 2; break;
case 4: m_NumOfColors = 16; break;
case 8: m_NumOfColors = 256;break;
case 16: m_NumOfColors =0xffff;break;
case 24: m_NumOfColors = 0xffffff;break;
}
}
else
m_NumOfColors = (DWORD) m_pBmpInfoHeader->biClrUsed;
return m_NumOfColors;
}
/**********************************************************
函数名:GetBytesPerPix
功能:获取位图表示每个像素点所用的字节数
入口参数:无
出口参数:字节数
说明:不同位数的彩色图像表示像素点所用的字节数不同,16位色
用两个字节,24位色用三个字节,8位色用一个字节等
**********************************************************/
DWORD BmpImage::GetBytesPerPix()
{
return m_pBmpInfoHeader->biBitCount/8;
}