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文件
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 BMP 文件读取并输出信息的程序示例: ```c #include <stdio.h> #include <stdint.h> // 定义 BMP 文件头结构体 #pragma pack(push, 1) typedef struct { uint16_t type; // 文件类型,必须为 BM uint32_t size; // 文件大小,单位为字节 uint16_t reserved1; // 保留字段1 uint16_t reserved2; // 保留字段2 uint32_t offset; // 数据偏移量,即 BMP 数据起始位置相对于文件头的偏移量 uint32_t dib_size; // DIB 数据结构大小,Windows BMP 文件中此值为 40 int32_t width; // 图像宽度,单位为像素 int32_t height; // 图像高度,单位为像素 uint16_t planes; // 位面数,必须为 1 uint16_t bpp; // 每个像素的位数,即色深 uint32_t compression; // 压缩方式,0 表示不压缩 uint32_t image_size; // 图像数据大小,单位为字节,如果不压缩则为 0 int32_t x_ppm; // 水平分辨率,单位为像素每米 int32_t y_ppm; // 垂直分辨率,单位为像素每米 uint32_t colors; // 调色板颜色数,如果为 0 表示使用默认值 uint32_t important; // 重要颜色数,如果为 0 表示所有颜色都重要 } bmp_file_header_t; #pragma pack(pop) int main() { FILE *file; bmp_file_header_t header; // 打开 BMP 文件 if ((file = fopen("test.bmp", "rb")) == NULL) { printf("Failed to open the file.\n"); return 1; } // 读取 BMP 文件头 if (fread(&header, sizeof(bmp_file_header_t), 1, file) != 1) { printf("Failed to read the file header.\n"); fclose(file); return 1; } // 输出 BMP 文件信息 printf("BMP type: %c%c\n", (char)(header.type & 0xFF), (char)(header.type >> 8)); printf("File size: %d bytes\n", header.size); printf("Data offset: %d bytes\n", header.offset); printf("Width: %d pixels\n", header.width); printf("Height: %d pixels\n", header.height); printf("Bit per pixel: %d\n", header.bpp); // 关闭 BMP 文件 fclose(file); return 0; } ``` 这个程序可以读取 BMP 文件头,并输出文件的类型、大小、数据偏移量、图像宽度和高度、像素位数等信息。注意,这个程序只能读取 Windows BMP 文件的头部信息,如果要读取完整的 BMP 文件,还需要根据文件头中的信息读取图像数据区。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值