BMP文件的读取

运行测试效果:

代码:

void  CMyView::OnReadBmp() 
{
// 读取BMP文件并显示
    CDC  * pDC  =  GetDC();

    CFileDialog dlg(TRUE);
    
if (dlg.DoModal() == IDOK)
    {
// 选择要打开的BMP图片
        strFilePath = dlg.GetPathName();
    }

    
if (strFilePath == "" )
    {
// 取消
         return ;
    }

    FILE 
* fp = fopen(strFilePath, " r " );

    BITMAPFILEHEADER fileheader;
    BITMAPINFO info;

    fread(
& fileheader, sizeof (fileheader), 1 ,fp);

    
if (fileheader.bfType != 0x4D42 )
    {
// 不是BMP位图文件
        pDC -> TextOut( 100 , 200 , " 无位图文件 请选择位图文件 " );
        fclose(fp);
        
return  ;
    }
    UCHAR 
* buffer  =  NULL;

    
// 读位图头部
    fread( & info.bmiHeader,  sizeof (BITMAPINFOHEADER),  1 , fp);
    
// 位图宽度
     long  width = info.bmiHeader.biWidth;
    
this -> width  =  width;
    
// 位图高度
     long  height = info.bmiHeader.biHeight;
    
this -> height  =  height;
    
    DWORD size;
    
if  (info.bmiHeader.biSizeImage  !=   0 )
    {
// 带颜色表
        size  =  info.bmiHeader.biSizeImage;
        
    }
    
else
    {
// 不带颜色表的
        size  =  info.bmiHeader.biHeight * info.bmiHeader.biWidth * 3 ;
    }
    buffer 
=   new  UCHAR[size]; // 分配缓冲区
     if  (buffer  ==  NULL)
    {
// 分配内存失败
        delete[] buffer;
        
return
    }
    
// 忽略头部字节
    fseek(fp,fileheader.bfOffBits, 0 );
    fread(buffer,size,
1 ,fp);

    
int  i,j;
    
#pragma  region 16 color
    
//  16色图的解析
     if (info.bmiHeader.biBitCount == 4 )
    {
        
int  pitch;
        
if (width % 8 == 0 )
            pitch
= width;
        
else
            pitch
= width + 8 - width % 8 ;

        RGBQUAD quad[
16 ];
        fseek(fp,fileheader.bfOffBits
- sizeof (RGBQUAD) * 16 , 0 );
        fread(quad,
sizeof (RGBQUAD) * 16 , 1 ,fp);

        
if (height > 0 )
        {
// height>0 表示图片颠倒
             for (i = 0 ; i < height; i ++ )
            {
                
for (j = 0 ; j < width; j ++ )
                {
                    
int  index;
                    
if (j % 2 == 0 )
                        index 
=  buffer[(i * pitch + j) / 2 ] / 16 ;
                    
if (j % 2 == 1 )
                        index 
=  buffer[(i * pitch + j) / 2 ] % 16 ;

                    UCHAR r
= quad[index].rgbRed;
                    UCHAR g
= quad[index].rgbGreen;
                    UCHAR b
= quad[index].rgbBlue;
                    pDC
-> SetPixel(j,height - i,RGB(r,g,b));
                }
            }
        }
        
else
        {
// 图片不颠倒
             for (i = 0 ; i < 0 - height; i ++ )
            {
                
for (j = 0 ; j < width; j ++ )
                {
                    
int  index;
                    
if (j % 2 == 0 )
                        index 
=  buffer[(i * pitch + j) / 2 ] / 16 ;

                    
if (j % 2 == 1 )
                        index 
=  buffer[(i * pitch + j) / 2 ] % 16 ;

                    UCHAR r
= quad[index].rgbRed;
                    UCHAR g
= quad[index].rgbGreen;
                    UCHAR b
= quad[index].rgbBlue;
                    pDC
-> SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma  endregion 16 color

#pragma  region 256 color
    
//  256色图的解析
     if (info.bmiHeader.biBitCount == 8 )
    {
        
int  pitch;
        
if (width % 4 == 0 )
        {
            pitch
= width;
        }
        
else
        {
            pitch
= width + 4 - width % 4 ;
        }

        RGBQUAD quad[
256 ];
        fseek(fp,fileheader.bfOffBits
- sizeof (RGBQUAD) * 256 , 0 );
        fread(quad,
sizeof (RGBQUAD) * 256 , 1 ,fp);

        
if (height > 0 )
        {
// height>0 表示图片颠倒
             for ( int  i = 0 ;i < height;i ++ )
            {
                
for ( int  j = 0 ;j < width;j ++ )
                {
                    
int  index = buffer[i * pitch + j];
                    UCHAR r
= quad[index].rgbRed;
                    UCHAR g
= quad[index].rgbGreen;
                    UCHAR b
= quad[index].rgbBlue;
                    pDC
-> SetPixel(j,height - i,RGB(r,g,b));
                }
            }
        }
        
else
        {
            
for ( int  i = 0 ;i < 0 - height;i ++ )
            {
                
for ( int  j = 0 ;j < width;j ++ )
                {
                    
int  index = buffer[i * pitch + j];
                    UCHAR r
= quad[index].rgbRed;
                    UCHAR g
= quad[index].rgbGreen;
                    UCHAR b
= quad[index].rgbBlue;
                    pDC
-> SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma  endregion 256 color

#pragma  region 24 bit
    
//  24位图解析
     if (info.bmiHeader.biBitCount == 24 )
    {
        
int  pitch = width % 4 ;
        
//  bgr
         if (height > 0 )
        {
// height>0 表示图片颠倒
             for ( int  i = 0 ;i < height;i ++ )
            {
                
int  realPitch = i * pitch;
                
for ( int  j = 0 ;j < width;j ++ )
                {
                    UCHAR b
= buffer[(i * width + j) * 3 + realPitch];
                    UCHAR g
= buffer[(i * width + j) * 3 + 1 + realPitch];
                    UCHAR r
= buffer[(i * width + j) * 3 + 2 + realPitch];
                    pDC
-> SetPixel(j,height - i,RGB(r,g,b));
                }
            }
        }
        
else
        {
            
for ( int  i = 0 ;i < 0 - height;i ++ )
            {
                
int  realPitch = i * pitch;
                
for ( int  j = 0 ;j < width;j ++ )
                {
                    UCHAR b
= buffer[(i * width + j) * 3 + realPitch];
                    UCHAR g
= buffer[(i * width + j) * 3 + 1 + realPitch];
                    UCHAR r
= buffer[(i * width + j) * 3 + 2 + realPitch];
                    pDC
-> SetPixel(j,i,RGB(r,g,b));
                }
            }
        }
    }
#pragma  endregion 24 bit

    
this -> ReleaseDC(pDC); // 释放掉绘制上下文
    delete[] buffer; // 释放缓冲区
    fclose(fp);  // 关闭BMP文件
}

你可能感兴趣的:(文件)