我采用下面的代码来打开bmp文件并显示位图,可是位图显示的时候颜色有点古怪,偏青蓝色,同时右边一小部分转移到左边来了,大家帮忙看看,谢谢!
CFile file;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
DWORD LineBytes;
DWORD NumColors;
DWORD i;
//打开文件
if(!file.Open(fileName,CFile::typeBinary|CFile::modeRead|CFile::shareDenyWrite,NULL))
{
AfxMessageBox("Cann't open this file!");
return FALSE;
}
// 读取文件头和信息头
file.Read((void*)&bf,sizeof(BITMAPFILEHEADER));
file.Read((void*)&bi,sizeof(BITMAPINFOHEADER));
//检查是不是位图文件
if(bf.bfType!=0x4d42)
{
AfxMessageBox("This file is not a bitmap file!");
file.Close();
return FALSE;
}
//判断这个文件是否已经遭到破坏
if(bf.bfSize!=file.GetLength())
{
AfxMessageBox("This file has been damaged!");
file.Close();
return FALSE;
}
//计算每一行的字节数
LineBytes=WIDTHBYTES(bi.biWidth*bi.biBitCount);
//计算图像实际用到的颜色数
if(bi.biClrUsed!=0)
NumColors=bi.biClrUsed;
else
switch(bi.biBitCount)
{
case 1:NumColors=2;break;
case 4:NumColors=16;break;
case 8:NumColors=256;break;
case 24:NumColors=0;break;
default:AfxMessageBox("There is something wrong with the color of the file!");
file.Close();
return FALSE;
}
//校验文件头偏移量
if(bf.bfOffBits!=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(DWORD)NumColors*sizeof(RGBQUAD))
{
AfxMessageBox("Invalid color numbers!");
file.Close();
return FALSE;
}
//动态分配内存
m_pBmInfo=(LPBITMAPINFO)new BYTE[file.GetLength()-sizeof(BITMAPFILEHEADER)];
m_pBmInfoHeader=(LPBITMAPINFOHEADER)m_pBmInfo;
//读取数据
file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
file.ReadHuge((void*)m_pBmInfo,file.GetLength()-sizeof(BITMAPFILEHEADER));
file.Close();
m_pBmBits=(BYTE*)(m_pBmInfo+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
if(NumColors!=0)//说明用到了调色板
m_bNeedPalette=TRUE;
else
m_bNeedPalette=FALSE;
//如果用到调色板,则建立之
if(NumColors!=0)
{
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
//为逻辑调色板分配局部内存
LOGPALETTE* pPal=(LOGPALETTE*)new BYTE(sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
pPal->palNumEntries=(WORD)NumColors;
pPal->palVersion=0x300;
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
for(i=0;i<NumColors;i++)
{
pPal->palPalEntry[i].peRed=m_pRGBTable->rgbRed;
pPal->palPalEntry[i].peGreen=m_pRGBTable->rgbGreen;
pPal->palPalEntry[i].peBlue=m_pRGBTable->rgbBlue;
pPal->palPalEntry[i].peFlags=(BYTE)0;
m_pRGBTable++;
}
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
m_pPalette->CreatePalette(pPal);
delete []pPal;
}
pDC->SetStretchBltMode(COLORONCOLOR);
::SetDIBitsToDevice(pDC->GetSafeHdc(),0,0,
m_pBmInfoHeader->biWidth,m_pBmInfoHeader->biHeight,
0,0,0,m_pBmInfoHeader->biHeight,
m_pBmBits,m_pBmInfo,DIB_RGB_COLORS);
CFile file;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
DWORD LineBytes;
DWORD NumColors;
DWORD i;
//打开文件
if(!file.Open(fileName,CFile::typeBinary|CFile::modeRead|CFile::shareDenyWrite,NULL))
{
AfxMessageBox("Cann't open this file!");
return FALSE;
}
// 读取文件头和信息头
file.Read((void*)&bf,sizeof(BITMAPFILEHEADER));
file.Read((void*)&bi,sizeof(BITMAPINFOHEADER));
//检查是不是位图文件
if(bf.bfType!=0x4d42)
{
AfxMessageBox("This file is not a bitmap file!");
file.Close();
return FALSE;
}
//判断这个文件是否已经遭到破坏
if(bf.bfSize!=file.GetLength())
{
AfxMessageBox("This file has been damaged!");
file.Close();
return FALSE;
}
//计算每一行的字节数
LineBytes=WIDTHBYTES(bi.biWidth*bi.biBitCount);
//计算图像实际用到的颜色数
if(bi.biClrUsed!=0)
NumColors=bi.biClrUsed;
else
switch(bi.biBitCount)
{
case 1:NumColors=2;break;
case 4:NumColors=16;break;
case 8:NumColors=256;break;
case 24:NumColors=0;break;
default:AfxMessageBox("There is something wrong with the color of the file!");
file.Close();
return FALSE;
}
//校验文件头偏移量
if(bf.bfOffBits!=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(DWORD)NumColors*sizeof(RGBQUAD))
{
AfxMessageBox("Invalid color numbers!");
file.Close();
return FALSE;
}
//动态分配内存
m_pBmInfo=(LPBITMAPINFO)new BYTE[file.GetLength()-sizeof(BITMAPFILEHEADER)];
m_pBmInfoHeader=(LPBITMAPINFOHEADER)m_pBmInfo;
//读取数据
file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
file.ReadHuge((void*)m_pBmInfo,file.GetLength()-sizeof(BITMAPFILEHEADER));
file.Close();
m_pBmBits=(BYTE*)(m_pBmInfo+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
if(NumColors!=0)//说明用到了调色板
m_bNeedPalette=TRUE;
else
m_bNeedPalette=FALSE;
//如果用到调色板,则建立之
if(NumColors!=0)
{
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
//为逻辑调色板分配局部内存
LOGPALETTE* pPal=(LOGPALETTE*)new BYTE(sizeof(LOGPALETTE)+NumColors*sizeof(PALETTEENTRY));
pPal->palNumEntries=(WORD)NumColors;
pPal->palVersion=0x300;
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
for(i=0;i<NumColors;i++)
{
pPal->palPalEntry[i].peRed=m_pRGBTable->rgbRed;
pPal->palPalEntry[i].peGreen=m_pRGBTable->rgbGreen;
pPal->palPalEntry[i].peBlue=m_pRGBTable->rgbBlue;
pPal->palPalEntry[i].peFlags=(BYTE)0;
m_pRGBTable++;
}
m_pRGBTable=(RGBQUAD*)(m_pBmInfo+sizeof(BITMAPINFOHEADER));
m_pPalette->CreatePalette(pPal);
delete []pPal;
}
pDC->SetStretchBltMode(COLORONCOLOR);
::SetDIBitsToDevice(pDC->GetSafeHdc(),0,0,
m_pBmInfoHeader->biWidth,m_pBmInfoHeader->biHeight,
0,0,0,m_pBmInfoHeader->biHeight,
m_pBmBits,m_pBmInfo,DIB_RGB_COLORS);
m_pBmBits=(BYTE*)(m_pBmInfo+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
是不是应该如下形式:
m_pBmBits=(BYTE*)(LPSTR(m_pBmInfo)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
再有bmbit()显示就行了,,(这个函数名我可能记错了自己看看msn)