CDib类(详解).doc
《CDib类(详解).doc》由会员分享,可在线阅读,更多相关《CDib类(详解).doc(7页珍藏版)》请在冰点文库上搜索。
#ifndef__CDIB_H
#define__CDIB_H
classCDib:
publicCObject
{
public:
RGBQUAD*m_pRGB; //位图颜色表指针
BYTE*m_pData,*m_pData2;//位图数据指针
UINTm_numberOfColors; //位图颜色数目
BOOLm_valid; //记录是否载入了位图文件
BITMAPFILEHEADERbitmapFileHeader; //位图文件头
BITMAPINFOHEADER*m_pBitmapInfoHeader; //位图信息头指针
BITMAPINFO *m_pBitmapInfo; //位图信息指针
intbyBitCount;
DWORDdwWidthBytes;
BYTE*pDib; //文件中位图总数据指针
DWORDsize; //位图总数据的长度
public:
CDib();
~CDib();
charm_fileName[256]; //记录文件名称
char*GetFileName(); //获取BMP位图文件名
BOOLIsValid(); //判断是否载入了位图文件,
DWORDGetSize(); //获取位图文件的大小
UINTGetWidth(); //获取位图宽度像素数
UINTGetHeight(); //获取位图高度像素数
UINTGetNumberOfColors(); //获取位图颜色数目
RGBQUAD*GetRGB(); //获取颜色表指针
BYTE*GetData(); //获取位图数据指针
BYTE*GetData2(); //获取位图数据指针
//voidLoadFile(constTCHAR*dibFileName); //载入BMP位图文件
//BOOLSaveFile(constTCHAR*pszFileName); //保存BMP位图文件
DWORDGetDibWidthBytes(); //获取位图的宽度字节数
BITMAPINFO*GetInfo(); //获取位图信息结构的指针
WORDPaletteSize(LPBYTElpDIB); //获取位图指针指向的位图的调色板的字节大小
WORDDIBNumColors(LPBYTElpDIB); //获取位图指针指向的位图的颜色数目
voidSaveFile(constCStringfilename);
public:
voidGradetoRGB();
voidRGBtoGrade();
voidLoadFile(constCStringdibFileName);
};
#endif
//然后就是方法的实现部分:
DIB.CPP
#include"stdafx.h"
#include"Dib.h"
#include"windowsx.h"
#defineWIDTHBYTES(bits)(((bits)+31)/32*4)
CDib:
:
CDib()
{
}
CDib:
:
~CDib()
{
GlobalFreePtr(m_pBitmapInfo);//释放在LoadFile中分配给m_pDib的内存资源
}
voidCDib:
:
LoadFile(constCStringdibFileName)
{
strcpy(m_fileName,dibFileName); //复制文件名字符串
CFiledibFile(m_fileName,CFile:
:
modeRead);//只读打开文件
dibFile.Read((void*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER)); //读取文件信息头数据
//判断文件是否为位图文件
if(bitmapFileHeader.bfType==0x4d42)
{
DWORDfileLength=dibFile.GetLength();//获取文件数据总长度
DWORDsize=fileLength-sizeof(BITMAPFILEHEADER);//计算位图文件位图总数据长度
BYTE*pDib=(BYTE*)GlobalAllocPtr(GMEM_MOVEABLE,size);//分配相应的内存资源
dibFile.Read((void*)pDib,size);//读取文件中位图总数据
dibFile.Close();//关闭位图文件
m_pBitmapInfo=(BITMAPINFO*)pDib;//指向位图信息,位图信息包括信息头和颜色表
m_pBitmapInfoHeader=(BITMAPINFOHEADER*)pDib;//指向位图信息头
m_pRGB=(RGBQUAD*)(pDib+m_pBitmapInfoHeader->biSize);//指向位图颜色表,指针沿数据向后移动m_pDibInfoHeader->biSize个字节
intm_numberOfColors=GetNumberOfColors();//获取颜色数目
if(m_pBitmapInfoHeader->biClrUsed==0)
m_pBitmapInfoHeader->biClrUsed=m_numberOfColors;//如果信息头没有记录使用的颜色数目,重新设置
DWORDcolorTableSize=m_numberOfColors*sizeof(RGBQUAD);//计算颜色表大小
m_pData=pDib+m_pBitmapInfoHeader->biSize+colorTableSize;//指向位图数据
if(m_pRGB==(RGBQUAD*)m_pData)
m_pRGB=NULL;
m_pBitmapInfoHeader->biSizeImage=GetSize();//在信息头中设置文件大小值
m_valid=TRUE;
}
else
{//打开的文件不是位图文件
m_valid=FALSE;
AfxMessageBox("这不是一个位图文件!
");
}
}
BOOLCDib:
:
IsValid()
{//判断是否打开了文件
returnm_valid;
}
char*CDib:
:
GetFileName()
{//文件已打开就可以获取文件名
returnm_fileName;
}
UINTCDib:
:
GetWidth()
{//如果信息头不为NULL,可以获取位图宽度像素数
return(UINT)m_pBitmapInfoHeader->biWidth;
}
UINTCDib:
:
GetHeight()
{//如果信息头不为NULL,可以获取位图高度像素数
return(UINT)m_pBitmapInfoHeader->biHeight;
}
DWORDCDib:
:
GetSize()
{
if(m_pBitmapInfoHeader->biSizeImage!
=0)
{//位图文件打开了,并且信息头的位图数据大小不为0就直接返回biSizeImage
returnm_pBitmapInfoHeader->biSizeImage;
}
else
{//文件已打开,但是信息头记录的位图大小为0,重新计算并返回位图数据大小
DWORDheight=(DWORD)GetHeight();
DWORDwidth=(DWORD)GetWidth();
returnheight*width;
}
}
DWORDCDib:
:
GetDibWidthBytes()//返回位图的宽度字节数
{
//获取位图像素位数和位图宽度像素数
byBitCount=m_pBitmapInfoHeader->biBitCount;
LONGnWidth=m_pBitmapInfoHeader->biWidth;
dwWidthBytes=(DWORD)m_pBitmapInfoHeader->biWidth;//如果位图的每个像素的位//数是8,那么位图的字节数等于像素数
if(byBitCount==1)dwWidthBytes=(nWidth+7)/8;//如果位图的每个像素的位数是1,//那么一个字节包含8个像素
elseif(byBitCount==4)dwWidthBytes=(nWidth+1)/2;//如果位图的每个像素的位数//是4,那么一个字节包含2个像素
elseif(byBitCount==24)dwWidthBytes=3*nWidth;//如果位图的每个像素的位数是//24,那么3个字节为一个像素
while((dwWidthBytes&3)!
=0)dwWidthBytes++;//位图的宽度字节数总是4的倍数
returndwWidthBytes;
}
UINTCDib:
:
GetNumberOfColors()
{
intnumberOfColors;
if((m_pBitmapInfoHeader->biClrUsed==0)&&
(m_pBitmapInfoHeader->biBitCount<9))
{//位图信息头的颜色数目为零,并且颜色位数小于9,
//从颜色位数判断颜色数目
switch(m_pBitmapInfoHeader->biBitCount)
{
case1:
numberOfColors=2;break;
case4:
numberOfColors=16;break;
case8:
numberOfColors=256;
}
}
else
//位图信息头的颜色数目不为零,直接获取颜色数目
numberOfColors=(int)m_pBitmapInfoHeader->biClrUsed;
returnnumberOfColors;
}
BYTE*CDib:
:
GetData()
{
returnm_pData;//返回位图数据
}
BYTE*CDib:
:
GetData2()
{//返回位图数据
if(GetRGB())
m_pData2=m_pData;
returnm_pData2;
}
RGBQUAD*CDib:
:
GetRGB()
{//返回位图颜色表
returnm_pRGB;
}
BITMAPINFO*CDib:
:
GetInfo()
{//返回位图信息
returnm_pBitmapInfo;
}
WORDCDib:
:
PaletteSize(LPBYTElpDIB)
{//如果位图指针有效,返回位图调色板的字节大小,
//否则返回0
return(DIBNumColors(lpDIB)*sizeof(RGBTRIPLE));
}
WORDCDib:
:
DIBNumColors(LPBYTElpDIB)
{ WORDwBitCount;
wBitCount=((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
switch(wBitCount)
{
case1:
return2;
case4:
return16;
case8:
return256;
default:
return0;
}
}
voidCDib:
:
SaveFile(constCStringfilename)
{
BITMAPFILEHEADERbmfHdr;//位图文件头
LPBITMAPINFOHEADERlpBI;//位图信息头指针
DWORDdwDIBSize;//位图数据大小
bmfHdr.bfType=0x4d42;//0x4d42编码指定文件是位图格式
lpBI=(LPBITMAPINFOHEADER)m_pBitmapInfoHeader;//取得位图信息头指针
dwDIBSize=*(LPDWORD)lpBI+PaletteSize((LPBYTE)lpBI);//计算位图信息头数据
if((lpBI->biCompression==BI_RLE8)||(lpBI->biCompression==BI_RLE4))
{//若位图是经过RLE压缩的,直接加上biSizeImage储存的位图空间量
dwDIBSize+=lpBI->biSizeImage;
}
else
{//若不是经过RLE压缩的,算法(biWidth*biBitCount+31)/32*4*biHeight算出biSizeImage的值
DWORDdwBmBitsSize;
dwBmBitsSize=WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))*lpBI->biHeight;
dwDIBSize+=dwBmBitsSize;
lpBI->biSizeImage=dwBmBitsSize;
}
bmfHdr.bfSize=dwDIBSize+sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1=0;
bmfHdr.bfReserved2=0;
bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+
lpBI->biSize+PaletteSize((LPBYTE)lpBI);
//创建新位图文件,并写入位图文件信息和数据
CFiledibFile(filename,CFile:
:
modeWrite|CFile:
:
modeCreate);
dibFile.Write(&bmfHdr,sizeof(BITMAPFILEHEADER));
dibFile.WriteHuge(lpBI,dwDIBSize);
dibFile.Close();
}
voidCDib:
:
RGBtoGrade()
{
if(GetRGB())
m_pData2=m_pData;
else
{
BYTEr,g,b;
intheight,wide,size;
height=GetHeight();
wide=GetWidth();
size=height*wide;
m_pData2=(BYTE*)GlobalAllocPtr(GMEM_MOVEABLE,size);
LONGlLineBytes=GetDibWidthBytes();
for(intj=0;j{
for(inti=0;i{
b=m_pData[j*lLineBytes+3*i];
g=m_pData[j*lLineBytes+3*i+1];
r=m_pData[j*lLineBytes+3*i+2];
m_pData2[j*wide+i]=(BYTE)(0.3*r+0.59*g+0.11*b);
}
}
}
}
voidCDib:
:
GradetoRGB()
{
if(GetRGB())
m_pData2=m_pData;
else
{
BYTEr,g,b;
intheight,wide;
height=GetHeight();
wide=GetWidth();
LONGlLineBytes=GetDibWidthBytes();
for(intj=0;j{
for(inti=0;i{
m_pData[(height-j-1)*lLineBytes+3*i]=m_pData2[(height-1-j)*wide+i];
m_pData[(height-j-1)*lLineBytes+3*i+1]=m_pData2[(height-1-j)*wide+i];
m_pData[(height-j-1)*lLineBytes+3*i+2]=m_pData2[(height-1-j)*wide+i];
}
}
}
}