热门标签:

BMP图像格式处理

转转大师PDF转换器

支持40多种格式转换,高效办公

宽泛来说,BMP图像是支持压缩的,他甚至支持jpeg压缩算法,但更一般的情况是,BMP用来存储所谓的真彩色影像,即24位的BitMap(位图),本文并不想刨BMP的祖坟,将它所有的细节抽丝剥茧一一展现,本文只想针对其最常见 的存储模式做个总结,备忘。

先来看BMP格式图像的文件总体结构:

从上到下,分别是三个结构体,代码表示如下(重要的成员已标注为红色):

struct header

{

    int16_t type;

    int32_t size; // 图像文件大小

    int16_t reserved1;

    int16_t reserved2;

    int32_t offbits; // bmp图像数据偏移量

}__attribute__((packed));

struct info

{

    int32_t size; // 本结构大小    

    int32_t width; // 图像宽度(单位像素)

    int32_t height; // 图像高度(单位像素)

    int16_t planes; // 总为零

 

    int16_t bit_count; // 色深

    int32_t compression; // 是否压缩

    int32_t size_img;

    int32_t X_pel;

    int32_t Y_pel;

    int32_t clrused;

    int32_t clrImportant;

}__attribute__((packed));

struct quad

{

    int8_t blue;

    int8_t green;

    int8_t red;

    int8_t reserved;

}__attribute__((packed));

看代码总是很无聊的,尤其是看不懂的代码!但是如果真要处理BMP图像数据,那就必须搞清楚以上代码了,挑几个重点说一下:

第一,定义了这三个结构体之后,一定要使用__attribute__((packed));来去除系统的地址对齐,否则读到的格式头会发生错误。

第二,header.size就是图像文件的大小(即文件总大小减去格式头大小)。

第三,header.offbits就是格式头的大小(可能是前两个结构体,也可能是三个结构体,因为第三个结构体quad可能有也可能没有)

第四,info.compression决定了格式头中是否含有quad结构体。

最后,要正确处理BMP图像还必须牢记在心的几个要点:

1,图像每一行所包含的字节数,必须是4的倍数,如果不够则会凑齐补足到够为止。比如某BMP图像色深为24bits,宽度为65像素,算下来一行的字节数是65乘以3等于195个字节,那在文件中将会增加一个额外的字节凑够196个字节来表示一行的数据量。

2,最后一行数据是图像的第一行,换句话说BMP是反着存储的。因此在读取BMP图像时一般从最后一行开始读取,然后读倒数第二行,以此类推,然后将读取到的数据依次刷新到显存,这样才能正确显示图像,否则图片看起来是反的。