我采用下面的代码来打开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);

解决方案 »

  1.   

    那么复杂,还不如使用API函数LoadImage来装入图片。可能是调色表设置得不对。还有m_pPalette创建之后,好像没有使用:应该调用pDC->SelectPalette来设置调色版。我说的可能不对,你的东西太复杂了。
      

  2.   

    Windows 程序设计第五版有打开位图的源代码,前面只要LoadImage就可以打开一个位图文件了,不需要从文件结构入手
      

  3.   

    我需要用得到的数据进行处理,不能用LoadImage的,另外我试验的是真彩图,那些调色板部分基本是没有用到的
      

  4.   

    从你说的情况应该是位图的数据位指针错了,问题应该出在这一行吧:
    m_pBmBits=(BYTE*)(m_pBmInfo+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
    是不是应该如下形式:
    m_pBmBits=(BYTE*)(LPSTR(m_pBmInfo)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD));
      

  5.   

    用LoadImage()不容易多,,
    再有bmbit()显示就行了,,(这个函数名我可能记错了自己看看msn)
      

  6.   

    24位的BMP图片,如果宽度和高度不是4的倍数,那么在每一行数据块后以00补齐的,这可能是造成你图像移位的原因??
      

  7.   

    24位的bmp位图不需要创建逻辑调色般的。用loadimage()载入位图,bitblt()显示位图,这是DDB(设备相关位图)用法。如果你向对载入的什么颜色格式得位图都是用的话,就要用DIB(设备无关位图)的方法,也就是你所用的船舰逻辑调色般的方法。建议你讲这几个函数集成在一个类中间,单独设置一个创建逻辑调色板函数,一个度如位图书局函数,一个显示函数,具体内容参考MSDN的DIBLOOK。
      

  8.   

    你这样写肯定有问题的!主要是BMP的格式的问题!
      

  9.   

    多谢YoungBoz(西山月),问题已经解决,正如您所料,改过之后可以显示图像了。但是不知道加这个强制类型转换LPSTR具体意义是什么?为什么加上之后就好了呢?