图片文件是有固定格式的,像BMP图片:文件头+位图的颜色数据。

文件头一般在读取的时候是使用下面的代码:

 
  
  1. BITMAPFILEHEADER fileheader={0}; 
  2.     fread(&fileheader,sizeof(fileheader),1,fp); 
  3.     if(fileheader.bfType!=0x4D42)  // 判断是否为BMP图片
  4.     { 
  5.         fclose(fp); 
  6.         return ; 
  7.     } 
  8.  
  9.     BITMAPINFOHEADER head; 
  10.     fread(&head,sizeof(BITMAPINFOHEADER),1,fp);  
  11.     long bmpWidth = head.biWidth;  //获取图片的宽
  12.     long bmpHeight = head.biHeight;  //获取图片的宽
  13.     WORD biBitCount = head.biBitCount; 
  14.     if(biBitCount != 24) // 是否为24位位图
  15.     { 
  16.         ::AfxMessageBox(_T("请选择24位位图!")); 
  17.         fclose(fp); 
  18.         return ; 
  19.     } 

文件读到这里了就要读到位图的颜色数据了,那么在读取前,我们需要知道数据的大小,这样才能把分配具体大学的缓冲区,之后把数据完整的读取到缓冲区内。

那么计算位图数据的大小一般用下面的代码去做。

 
  
  1. int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; 
  2. BYTE *pBmpBuf = new BYTE[totalSize];

在这些工作做完之后,我们就使用fread命令直接读取文件内容即可,直到读到文件结束。

整个具体的代码实现如下:

 

 
  
  1. FILE *fp=NULL; 
  2.     int ret = fopen_s(&fp,"D:\\11.bmp","rb"); 
  3.     if(fp==0)    
  4.     { 
  5.         return ; 
  6.     } 
  7.     BITMAPFILEHEADER fileheader={0}; 
  8.     fread(&fileheader,sizeof(fileheader),1,fp); 
  9.     if(fileheader.bfType!=0x4D42) 
  10.     { 
  11.         fclose(fp); 
  12.         return ; 
  13.     } 
  14.  
  15.     BITMAPINFOHEADER head; 
  16.     fread(&head,sizeof(BITMAPINFOHEADER),1,fp);  
  17.     long bmpWidth = head.biWidth; 
  18.     long bmpHeight = head.biHeight; 
  19.     WORD biBitCount = head.biBitCount; 
  20.     if(biBitCount != 24) 
  21.     { 
  22.         ::AfxMessageBox(_T("请选择24位位图!")); 
  23.         fclose(fp); 
  24.         return ; 
  25.     } 
  26.  
  27.     int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; 
  28.     BYTE *pBmpBuf = new BYTE[totalSize]; 
  29.     size_t size = 0; 
  30.     while(true
  31.     { 
  32.         int iret = fread(&pBmpBuf[size],1,1,fp); 
  33.         if(iret == 0) 
  34.             break
  35.         size = size + iret; 
  36.     } 
  37.     fclose(fp); 
  38.  
  39.     int i,j; 
  40.     CClientDC dc(this); 
  41.     int pitch=bmpWidth%4; 
  42.     for(i=0;i<bmpHeight;i++) 
  43.     { 
  44.         int realPitch=i*pitch; 
  45.         for(j=0;j<bmpWidth;j++) 
  46.         { 
  47.             dc.SetPixel(j,i,RGB( 
  48.                 pBmpBuf[(i*bmpWidth+j)*3+2+realPitch], 
  49.                 pBmpBuf[(i*bmpWidth+j)*3+1+realPitch], 
  50.                 pBmpBuf[(i*bmpWidth+j)*3+realPitch])); 
  51.         } 
  52.     } 
  53. delete [] pBmpBuf; pBmpBuf = NULL;
  54.     return ; 

这个打印出来的图片是倒过来的,具体什么原因,大家自己去想吧,学以致用才是好,这个代码我也是经常使用的。

如果对代码有问题的,可以回复我。