我能得到 BMP文件头数据结构数据和BMP位图信息头数据 但是我得到不了它的 BMP的实际的数据 怎么回事?
//想把BMP的实际的数据 放到m_pBMPBuffer中
BmpFileName = dlg.GetPathName();
if( !ScrFile.Open( BmpFileName, CFile::modeRead|CFile::typeBinary ) )
return ;
m_nFileLen = ScrFile.GetLength();

m_pBMPBuffer = new char[m_nFileLen + 1];  //想把BMP的实际的数据 放到m_pBMPBuffer中

if(!m_pBMPBuffer)
return ; // if(ScrFile.ReadHuge(&bf,m_nFileLen) != m_nFileLen)
//得到 BITMAPFILEHEADER   BMP文件头数据结构数据
if(ScrFile.ReadHuge((LPSTR)&bf,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
return ;
//  得到 BMP位图信息头数据
if(ScrFile.ReadHuge((LPSTR)&bi,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
return ;

// LineBytes 为每一行的字节数
LineBytes=(DWORD)WIDTHBYTES(bi.biWidth*bi.biBitCount);
/////////////////////////////
// ImgSize 为实际的图象数据占用的字节数
ImgSize=(DWORD)LineBytes*bi.biHeight;
//NumColors为实际用到的颜色数 , 即调色板数组中的颜色个数
if(bi.biClrUsed!=0)
//如果bi.biClrUsed不为零, 即为实际用到的颜色数
NumColors=(DWORD)bi.biClrUsed; 
else //否则,用到的颜色数为2biBitCount。
{
switch(bi.biBitCount)
{
case 1:
NumColors=2;
break;
case 4:
NumColors=16;
break;
case 8:
NumColors=256;
break;
case 24:
NumColors=0; //对于真彩色图,没用到调色板
break;
default: //不处理其它的颜色数,认为出错。
MessageBox("Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
ScrFile.Close();
}
}


}
if(bf.bfOffBits!=(DWORD)(NumColors*sizeof(RGBQUAD)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)))
{
//计算出的偏移量与实际偏移量不符,一定是颜色数出错
MessageBox("Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
ScrFile.Close();
}

bf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD)+ImgSize;

UINT nBytesRead = ScrFile.Read( (char *)m_pBMPBuffer, m_nFileLen-bf.bfOffBits );

解决方案 »

  1.   

    bmp有很多种格式,一定要弄清楚了。
      

  2.   

    24位是不用的,但是你的代码好象也处理其他颜色位数啊,
    switch(bi.biBitCount)
    {
    case 1:
    NumColors=2;
    break;
    case 4:
    NumColors=16;
    break;
    case 8:
    NumColors=256;
    break;
    case 24:
    NumColors=0; //对于真彩色图,没用到调色板
    break;
    default: //不处理其它的颜色数,认为出错。
    MessageBox("Invalid color numbers!","Error Message",MB_OK|MB_ICONEXCLAMATION);
    ScrFile.Close();
    }
      

  3.   

    你读文件的时候没考虑过读取位置吧,每次都是直接READ,要先SEEK吧
    if(ScrFile.ReadHuge(&bf,m_nFileLen) != m_nFileLen)
    //得到 BITMAPFILEHEADER   BMP文件头数据结构数据
    if(ScrFile.ReadHuge((LPSTR)&bf,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER))
    return ;
    //  得到 BMP位图信息头数据
    if(ScrFile.ReadHuge((LPSTR)&bi,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER))
    return ;
      

  4.   

    当NumColors不为0时,你应先读取调色板,否则此时的文件指针没有指向数据区,你可以用file.Seek(bf.bfOffBits, CFile::begin);来确保文件指针指向数据区后再读取数据区。当你顺序读取位图的各个结构时,是不用Seek的。
      

  5.   

    TO [ Arlene_cn(茴香) ]我在UINT nBytesRead = ScrFile.Read( (char *)m_pBMPBuffer, m_nFileLen-bf.bfOffBits );
    的前面也用过
      ScrFile.Seek(bf.bfOffBits, CFile::begin);
    UINT nBytesRead = ScrFile.Read( (char *)m_pBMPBuffer, m_nFileLen-bf.bfOffBits );这是m_pBMPBuffer里面有数据,但我觉得不是数据区的数据。
      

  6.   

    你根据什么判断m_pBMPBuffer里面的数据不是数据区的数据,是因为图像显示不正常吗?下面是我的一个读BMP文件的函数,其中m_Image的定义如下:struct _tagImage
    {
    BITMAPFILEHEADER bf;
    BITMAPINFOHEADER bi;
    RGBQUAD quad[256];
    int cx;                // The width of the image in pixels
    int cy;                // The height of the image in pixels
    BYTE* data;            // The image pixel data
    };_tagImage m_Image;BOOL CMyDoc::ReadBMPFile(LPCSTR lpszFileName)
    {
        CFile file;
        if (!file.Open(lpszFileName, CFile::modeRead))
        {
            return FALSE;
        }    // 读文件头
        file.Read(&m_Image.bf, sizeof(BITMAPFILEHEADER));    if (m_Image.bf.bfType != 0x4d42) // 0x42 = "B" 0x4d = "M"
        {
            file.Close();
            return FALSE;
        }    // 读信息头
        BITMAPINFOHEADER* pBIH = &(m_Image.bi);
        file.Read(pBIH, sizeof(BITMAPINFOHEADER));    // 读调色板
        if (pBIH->biBitCount < 24)
        {
            int nSizeTable = (1 << pBIH->biBitCount) * sizeof(RGBQUAD);
            file.Read(m_Image.quad, nSizeTable);
        }    ASSERT(file.GetPosition() == m_Image.bf.bfOffBits);    // 读数据区
        DWORD dwDataSize = pBIH->biSizeImage;
        if (pBIH->biSizeImage == 0)
        {
            dwDataSize = WIDTHBYTES(pBIH->biWidth, pBIH->biBitCount) * pBIH->biHeight;
        }    file.Read(m_Image.data, dwDataSize);
        file.Close();    m_Image.cx = pBIH->biWidth;
        m_Image.cy = pBIH->biHeight;    return TRUE;
    }
      

  7.   

    TO  [Arlene_cn(茴香)]   读数据区的关键地方没有写WIDTHBYTES( ) 里面是什么
       写完我就结帖加分了。谢谢
     
    // 读数据区
        DWORD dwDataSize = pBIH->biSizeImage;
        if (pBIH->biSizeImage == 0)
        {
            dwDataSize = WIDTHBYTES(pBIH->biWidth, pBIH->biBitCount) * pBIH->biHeight;
        }
      

  8.   

    谢谢了.现在我已经知道了
    dwDataSize =pBIH->biBitCount  * pBIH->biWidth * pBIH->biHeight;BMP数据也得到了.