//求大神指点什么地方出错了
class ImageDib{public:
char * m_pImgDate; //图像数据指针
LPRGBQUAD m_lpColorTable; //图像颜色表指针
int m_nBitCount; //每像素占的位数
private:
LPBYTE m_lpDib; //指向dip的指针
HPALETTE m_hPalette; //逻辑调色板句柄
int m_nColorTableLength; //颜色表长度(多少个表项)
public:
int m_imgWidth; //图像的宽,以像素为单位
int m_imgHeight; //图像的高,以像素为单位
LPBITMAPINFOHEADER m_lpBmpInfpHead; //图像信息头指针
//成员函数
public:
ImageDib(); //构造函数
~ImageDib(); //析构函数
BOOL Read(LPCTSTR lpszPathName); //dip读函数
BOOL Write(LPCTSTR lpszPathName); //dip写函数
int ComputeColorTabalLength(int nBitCount); //计算指针长度
BOOL Draw(CDC* pDC,CPoint origin,CSize size); //图形绘制
CSize GetDimensions(); //读取像素维数
void ReplaceDip(CSize size,int nBitCount,LPRGBQUAD lpColorTable,
char pImgData); //用新的数据替换dip
private:
void MakePalette(); //创建逻辑调色板
void Empty(); //清理空间
};
ImageDib::ImageDib()
{
m_lpDib=NULL; // 初始化m-lpdip为空
m_lpColorTable=NULL; // 图像表指针为空
m_pImgDate=NULL; // 图像数据指针为空
m_lpBmpInfpHead=NULL; // 图像信息头为空
m_hPalette=NULL; // 调色板为空
return 0;
}
ImageDib::~ImageDib()
{
//释放m-lpdip所指向的空间
if (m_lpDib !=NULL)
{
delete []m_lpDib;
}
//如果有调色板,释放调色板缓冲区
if (m_hPalette !=NULL)
{
delete [] m_hPalette;
}
}
ImageDib::ImageDib(CSize size , int nBitcount ,LPRGBQUAD lpColorTable,char * pImgData){
//如果没有位图像数据传入,我们认为空的dip,此时不分配dib内存
if (pImgData==NULL)
{
m_lpDib=NULL; //m-lpdip为空
m_lpColorTable=NULL; //图像表指针为空
m_pImgDate=NULL; //图像数据指针为空
m_lpBmpInfpHead=NULL; //图像信息头为空
m_hPalette=NULL; //调色板为空
}
else{//如果有位图像数据传入
//则图像的宽,高,每像素位数等成员变量赋值
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=nBitcount;
//根据每像素位数,计算颜色长度
m_nColorTableLength=ComputeColorTabalLength(nBitcount);
//每行像素所占的字节数,必须扩展成4的倍数
int lineByte=(m_imgWidth*nBitcount/8+3)/4*4;
//位图数据缓冲区的大小(图像大小)
int imgBufSize=m_imgHeight*lineByte;
//为m_lpDip一次性分配内存,生成DIB结构
m_lpDib=new BYTE[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize];
//填写BITMAPINFOHEADER结构
m_lpBmpInfpHead=(LPBITMAPINFOHEADER) m_lpDib;
m_lpBmpInfpHead->biSize=sizeof(BITMAPINFOHEADER);
m_lpBmpInfpHead->biWidth=m_imgWidth;
m_lpBmpInfpHead->biHeight=m_imgHeight;
m_lpBmpInfpHead->biPlanes=1; //目标设备平面数设置为一
m_lpBmpInfpHead->biBitCount=m_nBitCount;
m_lpBmpInfpHead->biCompression=BI_RGB; //压缩类型,不压缩为为0
m_lpBmpInfpHead->biSizeImage=0; //压缩图像大小的字节数,费压缩图像为0
m_lpBmpInfpHead->biXPelsPerMeter=0; //水平分辨率
m_lpBmpInfpHead->biYPelsPerMeter=0; //垂直分辨率
m_lpBmpInfpHead->biClrUsed=m_nColorTableLength;//使用颜色的彩数
m_lpBmpInfpHead->biClrImportant=m_nColorTableLength; //重要色彩数,0表示都重要;
//调色板句柄初始化为空,有颜色时,makepalette()函数要生成新的调色板
m_hPalette = NULL;
//如果有颜色表,则将颜色表复制进dib的颜色表位置
if (m_nColorTableLength ! = 0)
{
//m_lpColorTable指向dib颜色表的起始位置
m_lpColorTable = (LPRGBQUAD) (m_lpDib+sizeof(BITMAPINFOHEADER));
//颜色表复制
memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
//创建逻辑调色板
MakePalette();
}
//m_pImgDate指向dib位图数据起始位置
m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
//复制图像数据进dib位图数据区
memcpy(m_pImgDate,pImgData,imgBufSize);
}
}
BOOL ImageDib::Read(LPCTSTR lpszPathname)
{
//读模式打开文件
CFile file;
if(!file.Open(lpszPathname,CFile::modeRead|CFile::shareDenyWrite))
return FALSE;
BITMAPINFOHEADER bmfh;
//读取 BITMAPINFOHEADER 结构变量bmfh中
int nCount=file.Read((LPVOID)&bmfh,sizeof(BITMAPFILEHEADER));
//为m_lpDip分配空间,读取dib进内存
if(m_lpDib!=NULL)
delete []m_lpDib;
m_lpDib=new BYTE[file.GetLength()]-sizeof(BITMAPFILEHEADER);
file.Read(m_lpDib,file.GetLength() -sizeof(BITMAPFILEHEADER));
//m_lpBmpInfpHead位置为 m_lpDib起始位置
m_lpBmpInfpHead= (LPBITMAPINFOHEADER)m_lpDib;
//为成员变量赋值
m_imgWidth=m_lpBmpInfpHead->biWidth;
m_imgHeight=m_lpBmpInfpHead->biHeight;
m_nBitCount=m_lpBmpInfpHead->biBitCount;
//计算颜色长度
m_nColorTableLength=ComputeColorTabalLength(m_lpBmpInfpHead->biBitCount);
//如果有颜色表,则创建逻辑调色板
m_hPalette = NULL;
if (m_nColorTableLength!=0)
{
(LPRGBQUAD)(m_lpDib+sizeof(BITMAPINFOHEADER));
MakePalette();
}
//m_pImgDate指向dib的位图位图数据起始位置
m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
return TRUE;
}
BOOL ImageDib::Write(LPCTSTR lpszPathName){
//以写模式打开文件
CFile file;
if (!file.Open(lpszPathName,CFile::modeCreate|CFile::modeReadWrite|CFile::shareExclusive))
{
return FALSE;
}
//填写文件头结构
BITMAPINFOHEADER bmfh;
bmfh.bfType=0x4d42; //'bm'
bmfh.biSize=0;
bmfh.bfReserverd1=bmfh.bfReserver2 = 0;
bmfh.bfoffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
try
{
//文件头结构写进文件
file.Write((LPVOID) & bmfh,sizeof(BITMAPFILEHEADER));
//文件信息头结构写进文件
file.Write(m_lpBmpInfpHead,sizeof(BITMAPINFOHEADER));
//如果有颜色表的话,颜色表写进文件
if (m_nColorTableLength!=0)
{
file.Write(m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
}
//位图数据写进文件
int imgBuffSize = (m_imgWidth*m_nBitCount/8+3)/4*4*m_imgHeight;
file.Write(m_pImgDate,imgBuffSize);
}
catch (CException* pe)
{
pe->Delete();
AfxMessageBox("write error");
return FALSE;
}
//函数返回
return TRUE;
}
void ImageDib::MakePalette(){
//如果颜色表长度为0,则不创建逻辑调色板
if (m_nColorTableLength==0)
{
return ;
}
//删除旧的逻辑调色板句柄
if (m_hPalette!=NULL)::DeleteObject(m_hPalette);
//申请空间,根据颜色表生成LOGPALETTE结构
LPLOGPALETTE pLogPal = (LPLOGPALETTE) new char[2*sizeof(WORD)+m_nColorTableLength*sizeof(PALETTEENTRY)];
pLogPal->palVersion=0x30;
pLogPal->palNumEntries = m_nColorTableLength;
LPRGBQUAD m_lpDibQuad = (LPRGBQUAD) m_lpColorTable;
for(int i = 0 ; i<m_nColorTableLength;i++){
pLogPal->palPalEntry[i].peRed=m_lpDibQuad->rgbRed;
pLogPal->palPalEntry[i].peBlue=m_lpDibQuad->rgbBlue;
pLogPal->palPalEntry[i].peGreen=m_lpDibQuad->rgbGreen;
pLogPal->palPalEntry[i].peFlags=0;
m_lpDibQuad++
}
//创建逻辑调色板
m_hPalette=::CreatePalette(pLogPal);
//释放空间
delete pLogPal;
}
int ImageDib::ComputeColorTabalLength(int nBitCount){
int colorTableLength;
switch (nBitCount)
{
case 1:
colorTableLength=2;
break;
case 4:
colorTableLength=16;
break;
case 8:
colorTableLength=256;
break;
case 16:
case 24:
case 32:
colorTableLength=0;
break;
default:
ASSERT(FALSE);
}
ASSERT((colorTableLength>=0)&&(colorTableLength<=256));
return colorTableLength;
}
BOOL ImageDib::Draw(CDC* pDC,CPoint origin,CSize size )
{
HPALETTE hOldPal =NULL; //旧的调色板句柄
if (m_lpDib==NULL) //如果dib为空,则返回0
{
return FALSE;
}
if (m_hPalette !=NULL) //如果dib有调色板
{ //将调色板选进设备环境中
hOldPal=::SelectPalette(pDC->GetSafeHdc());
pDC->RealizePalette();
}
pDC->SetStretchBltMode(COLORONCOLOR); //设置位图伸缩模式
//将dib在pdc所指的设备上进行显示
::StretchDIBits(pDC->GetSafeHdc(),origin.x,origin.y,size.cx,size.cy,0,0,
m_lpBmpInfpHead->biWidth,m_lpBmpInfpHead->biHeight,
m_pImgDate,(LPBITMAPINFO)m_lpBmpInfpHead,DIB_RGB_COLORS,SRCCOPY);
if (hOldPal!=NULL)
{//恢复旧的调色板
::SelectPalette(pDC->GetSafeHdc(),hOldPal,TRUE);
}
return TRUE;
}
CSize ImageDib::GetDimensions(){
if (m_lpDib==NULL)
{
return CSize(0,0);
}
return CSize(m_imgWidth,m_imgHeight);
}
void ImageDib::Empty(){ //释放dib内存缓冲区
if (m_lpDib!=NULL)
{
delete [] m_lpDib;
m_lpDib=NULL; //初始化m-lpdip为空
m_lpColorTable=NULL; //图像表指针为空
m_pImgDate=NULL; //图像数据指针为空
m_lpBmpInfpHead=NULL; //图像信息头为空
m_hPalette=NULL; //调色板为空
}
//释放逻辑调色板缓冲区
if (m_hPalette!=NULL)
{
::DeleteObject(m_hPalette);
m_hPalette=NULL;
}
}
void ImageDib::ReplaceDip(CSize size,int nBitCount,LPRGBQUAD lpColorTable,
char pImgData){
//释放原dib所占空间
Empty();
//成员变量赋值
m_imgWidth=size.cx;
m_imgHeight=size.cy;
m_nBitCount=nBitcount;
//计算颜色表的长度
m_nColorTableLength=ComputeColorTabalLength(nBitcount);
//每行像素所占字节数,扩展成4的倍数
int lineByte =(m_imgWidth*nBitCount/8+3)/4*4;
//位图数据缓冲区的大小(图像大小)
int imgBufSize=m_imgHeight*lineByte;
//为m_lpDip重新分配内存,存放新的DIB结构
m_lpDib=new BYTE[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength+imgBufSize];
//填写BITMAPINFOHEADER结构
m_lpBmpInfpHead=(LPBITMAPINFOHEADER) m_lpDib;
m_lpBmpInfpHead->biSize=sizeof(BITMAPINFOHEADER);
m_lpBmpInfpHead->biWidth=m_imgWidth;
m_lpBmpInfpHead->biHeight=m_imgHeight;
m_lpBmpInfpHead->biPlanes=1; //目标设备平面数设置为一
m_lpBmpInfpHead->biBitCount=m_nBitCount;
m_lpBmpInfpHead->biCompression=BI_RGB; //压缩类型,不压缩为为0
m_lpBmpInfpHead->biSizeImage=0; //压缩图像大小的字节数,费压缩图像为0
m_lpBmpInfpHead->biXPelsPerMeter=0; //水平分辨率
m_lpBmpInfpHead->biYPelsPerMeter=0; //垂直分辨率
m_lpBmpInfpHead->biClrUsed=m_nColorTableLength;//使用颜色的彩数
m_lpBmpInfpHead->biClrImportant=m_nColorTableLength; //重要色彩数,0表示都重要;
//调色板置空
m_hPalette = NULL;
//如果有颜色表,则将颜色表复制进dib的颜色表位置,并创建逻辑调色板
if (m_nColorTableLength ! = 0)
{
//m_lpColorTable指向dib颜色表的起始位置
m_lpColorTable = (LPRGBQUAD) (m_lpDib+sizeof(BITMAPINFOHEADER));
//颜色表复制
memcpy(m_lpColorTable,lpColorTable,sizeof(RGBQUAD)*m_nColorTableLength);
//创建逻辑调色板
MakePalette();
}
//m_pImgDate指向dib位图数据起始位置
m_pImgDate=(LPBYTE)m_lpDib+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*m_nColorTableLength;
//复制图像数据进dib位图数据区
memcpy(m_pImgDate,pImgData,imgBufSize);
}