运行测试效果:

BMP文件的读取_BMP

代码:

  1. void CMyView::OnReadBmp()   
  2. {//读取BMP文件并显示  
  3.     CDC *pDC = GetDC();  
  4.  
  5.     CFileDialog dlg(TRUE);  
  6.     if(dlg.DoModal()==IDOK)  
  7.     {//选择要打开的BMP图片  
  8.         strFilePath=dlg.GetPathName();  
  9.     }  
  10.  
  11.     if(strFilePath=="")  
  12.     {//取消  
  13.         return;  
  14.     }  
  15.  
  16.     FILE *fp=fopen(strFilePath,"r");  
  17.  
  18.     BITMAPFILEHEADER fileheader;  
  19.     BITMAPINFO info;  
  20.  
  21.     fread(&fileheader,sizeof(fileheader),1,fp);  
  22.  
  23.     if(fileheader.bfType!=0x4D42)  
  24.     {//不是BMP位图文件  
  25.         pDC->TextOut(100,200,"无位图文件 请选择位图文件");  
  26.         fclose(fp);  
  27.         return ;  
  28.     }  
  29.     UCHAR *buffer = NULL;  
  30.  
  31.     //读位图头部  
  32.     fread(&info.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp);  
  33.     //位图宽度  
  34.     long width=info.bmiHeader.biWidth;  
  35.     this->width = width;  
  36.     //位图高度  
  37.     long height=info.bmiHeader.biHeight;  
  38.     this->height = height;  
  39.       
  40.     DWORD size;  
  41.     if (info.bmiHeader.biSizeImage != 0)  
  42.     {//带颜色表  
  43.         size = info.bmiHeader.biSizeImage;  
  44.           
  45.     }  
  46.     else 
  47.     {//不带颜色表的  
  48.         size = info.bmiHeader.biHeight*info.bmiHeader.biWidth*3;  
  49.     }  
  50.     buffer = new UCHAR[size];//分配缓冲区  
  51.     if (buffer == NULL)  
  52.     {//分配内存失败  
  53.         delete[] buffer;  
  54.         return;   
  55.     }  
  56.     //忽略头部字节  
  57.     fseek(fp,fileheader.bfOffBits,0);  
  58.     fread(buffer,size,1,fp);  
  59.  
  60.     int i,j;  
  61.       
  62. #pragma region 16 color  
  63.     // 16×××的解析  
  64.     if(info.bmiHeader.biBitCount==4)  
  65.     {  
  66.         int pitch;  
  67.         if(width%8==0)  
  68.             pitch=width;  
  69.         else 
  70.             pitch=width+8-width%8;  
  71.  
  72.         RGBQUAD quad[16];  
  73.         fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*16,0);  
  74.         fread(quad,sizeof(RGBQUAD)*16,1,fp);  
  75.  
  76.         if(height>0)  
  77.         {//height>0 表示图片颠倒  
  78.             for(i=0; i<height; i++)  
  79.             {  
  80.                 for(j=0; j<width; j++)  
  81.                 {  
  82.                     int index;  
  83.                     if(j%2==0)  
  84.                         index = buffer[(i*pitch+j)/2]/16;  
  85.                     if(j%2==1)  
  86.                         index = buffer[(i*pitch+j)/2]%16;  
  87.  
  88.                     UCHAR r=quad[index].rgbRed;  
  89.                     UCHAR g=quad[index].rgbGreen;  
  90.                     UCHAR b=quad[index].rgbBlue;  
  91.                     pDC->SetPixel(j,height-i,RGB(r,g,b));  
  92.                 }  
  93.             }  
  94.         }  
  95.         else 
  96.         {//图片不颠倒  
  97.             for(i=0; i<0-height; i++)  
  98.             {  
  99.                 for(j=0; j<width; j++)  
  100.                 {  
  101.                     int index;  
  102.                     if(j%2==0)  
  103.                         index = buffer[(i*pitch+j)/2]/16;  
  104.  
  105.                     if(j%2==1)  
  106.                         index = buffer[(i*pitch+j)/2]%16;  
  107.  
  108.                     UCHAR r=quad[index].rgbRed;  
  109.                     UCHAR g=quad[index].rgbGreen;  
  110.                     UCHAR b=quad[index].rgbBlue;  
  111.                     pDC->SetPixel(j,i,RGB(r,g,b));  
  112.                 }  
  113.             }  
  114.         }  
  115.     }  
  116. #pragma endregion 16 color  
  117.  
  118. #pragma region 256 color  
  119.     // 256×××的解析  
  120.     if(info.bmiHeader.biBitCount==8)  
  121.     {  
  122.         int pitch;  
  123.         if(width%4==0)  
  124.         {  
  125.             pitch=width;  
  126.         }  
  127.         else 
  128.         {  
  129.             pitch=width+4-width%4;  
  130.         }  
  131.  
  132.         RGBQUAD quad[256];  
  133.         fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*256,0);  
  134.         fread(quad,sizeof(RGBQUAD)*256,1,fp);  
  135.  
  136.         if(height>0)  
  137.         {//height>0 表示图片颠倒  
  138.             for(int i=0;i<height;i++)  
  139.             {  
  140.                 for(int j=0;j<width;j++)  
  141.                 {  
  142.                     int index=buffer[i*pitch+j];  
  143.                     UCHAR r=quad[index].rgbRed;  
  144.                     UCHAR g=quad[index].rgbGreen;  
  145.                     UCHAR b=quad[index].rgbBlue;  
  146.                     pDC->SetPixel(j,height-i,RGB(r,g,b));  
  147.                 }  
  148.             }  
  149.         }  
  150.         else 
  151.         {  
  152.             for(int i=0;i<0-height;i++)  
  153.             {  
  154.                 for(int j=0;j<width;j++)  
  155.                 {  
  156.                     int index=buffer[i*pitch+j];  
  157.                     UCHAR r=quad[index].rgbRed;  
  158.                     UCHAR g=quad[index].rgbGreen;  
  159.                     UCHAR b=quad[index].rgbBlue;  
  160.                     pDC->SetPixel(j,i,RGB(r,g,b));  
  161.                 }  
  162.             }  
  163.         }  
  164.     }  
  165. #pragma endregion 256 color  
  166.  
  167. #pragma region 24 bit  
  168.     // 24位图解析  
  169.     if(info.bmiHeader.biBitCount==24)  
  170.     {  
  171.         int pitch=width%4;  
  172.         // bgr  
  173.         if(height>0)  
  174.         {//height>0 表示图片颠倒  
  175.             for(int i=0;i<height;i++)  
  176.             {  
  177.                 int realPitch=i*pitch;  
  178.                 for(int j=0;j<width;j++)  
  179.                 {  
  180.                     UCHAR b=buffer[(i*width+j)*3+realPitch];  
  181.                     UCHAR g=buffer[(i*width+j)*3+1+realPitch];  
  182.                     UCHAR r=buffer[(i*width+j)*3+2+realPitch];  
  183.                     pDC->SetPixel(j,height-i,RGB(r,g,b));  
  184.                 }  
  185.             }  
  186.         }  
  187.         else 
  188.         {  
  189.             for(int i=0;i<0-height;i++)  
  190.             {  
  191.                 int realPitch=i*pitch;  
  192.                 for(int j=0;j<width;j++)  
  193.                 {  
  194.                     UCHAR b=buffer[(i*width+j)*3+realPitch];  
  195.                     UCHAR g=buffer[(i*width+j)*3+1+realPitch];  
  196.                     UCHAR r=buffer[(i*width+j)*3+2+realPitch];  
  197.                     pDC->SetPixel(j,i,RGB(r,g,b));  
  198.                 }  
  199.             }  
  200.         }  
  201.     }  
  202. #pragma endregion 24 bit  
  203.  
  204.     this->ReleaseDC(pDC);//释放掉绘制上下文  
  205.     delete[] buffer;//释放缓冲区  
  206.     fclose(fp); //关闭BMP文件