如何读入位图(五)

C++来读入位图就更加简单了:

BOOL CDib::OpenImage(CString fileName)

{

       BITMAPFILEHEADER m_bmfh;

BITMAPINFOHEADER m_bmih;

BYTE *img;

       //如果文件名位空,则给出警告并退出

       if(!fileName)

       {

              AfxMessageBox("文件名不能位空");

              return false;

       }

       //建立CFile类的对象dib

       CFile dib;

       //打开文件

       if(!dib.Open(fileName,CFile::modeRead))

       {

              //打开失败,则给出警告并退出

              AfxMessageBox("打开文件失败");

              return false;

       }

       //读取位图文件头

       if(dib.Read(&m_bmfh,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER))

       {

              //读取失败,则给出警告并退出

              AfxMessageBox("读取位图文件头失败");

              return false;

       }

       //读取位图信息头

       if(dib.Read(&m_bmih,sizeof(BITMAPINFOHEADER))!=sizeof(BITMAPINFOHEADER))

       {

              AfxMessageBox(“读取位图信息头失败”);

              return false;

       }

       //跳过调色板

       dib.Seek(m_bmfh.biOffBits,CFile::begin);

       //为像素数据分配空间

       img=new BYTE[m_bmih.biHeight*((m_bmih.biWidth*m_bmih.biBitCount+31)/32*4)];

       //读入像素数据

       dib.Read(img, m_bmih.biHeight*((m_bmih.biWidth*m_bmih.biBitCount+31)/32*4));

       //关闭文件

       dib.Close();

       return true;

}

 

至于显示的话,就是一个StretchDIBits函数而已,不多说了。下面来看看如何用C++来保存位图:

BOOL CDib::SaveImage(CString fileName)

{

       //如果文件名位空,则给出警告并退出

       if(!fileName)

       {

              AfxMessageBox("文件名不能位空");

              return false;

       }

       //创建CFile类的对象dib

       CFile dib;

       //打开要保存的文件

       if(!dib.Open(fileName,CFile::modeCreate | CFile::typeBinary | CFile::modeWrite))

       {

              AfxMessageBox("打开文件失败");

              return false;

       }

       //保存文件头

       dib.Write(&m_bmfh,sizeof(BITMAPFILEHEADER));

       //保存位图信息头

       dib.Write(&m_bmih,sizeof(BITMAPINFOHEADER));

       //如果是8位位图,还需要保存调色板内容

       if(m_bmih->biBitCount==8)

       {

              //如果没有用到所有的颜色

              if(m_bmih ->biClrUsed!=0)

              {

                     dib.Write(m_lpRgbQuad, m_bmih ->biClrUsed*sizeof(RGBQUAD));

              }

              else

              {

                     //用到了所有的256种颜色

                     dib.Write(m_lpRgbQuad,256*sizeof(RGBQUAD));

              }

       }

       //保存像素数据

       dib.Write(m_lpDibData,m_bmih ->biHeight*GetLineBytes());

       //给出保存成功的提示

       AfxMessageBox("保存成功");

       //关闭文件

       dib.Close();

       return true;

}

其中GetLineBytes()函数就是有图像的宽度和位数得到图像每行像素所占的字节数。计算公式如下:lineBytes=(width*bitCount+31)/32*4;为什么要计算图像每行像素所占的字节数?是因为在保存BMP位图的时候,每行所占的字节数必须是4的倍数,如果不是要补齐。这点跟sizeof用在结构体的时候的字节补齐很类似。

原文地址:https://www.cnblogs.com/djcsch2001/p/1960206.html