Bitmap BMP图像信息验证
参考文章
例程目的
BMP进过压缩以后可能会出现各种各样的问题,比如所图像大小、偏移位置出错,文件大小出错等等问题。因此在使用BMP图片前需要验证BMP图像信息是否有误
一、Bitmap图像结构
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <math.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
/* 字节对齐 */
#pragma pack(1)
/* 位图文件头 */
typedef struct
{
u16 FileType; /* 文件类型标记 */
u32 FileSize; /* 文件大小 */
u16 Reserve1; /* 保留1 */
u16 Reserve2; /* 保留2 */
u32 ImgDataOffset; /* 图像数据偏移 */
}BitMapFileHeader_TypeDef, * pBitMapFileHeader_TypeDef;
/* 位图信息头 */
typedef struct
{
u32 InfoHeaderSize; /* 信息头大小 */
u32 ImgWidth; /* 图像宽度 */
u32 ImgHeight; /* 图像高度 */
u16 ColorPlanes; /* 颜色平面数 */
u16 PixelsBits; /* 像素位数 */
u32 CompresType; /* 压缩类型 */
u32 ImgDataSize; /* 图像数据大小 */
u32 HorResolut; /* 水平分辨率 */
u32 VerResolut; /* 垂直分辨率 */
u32 ColorPalette; /* 调色板大小 */
u32 ColorImportant; /* 重要颜色数 */
}BitMapInfoHeader_TypeDef, * pBitMapInfoHeader_TypeDef;
/* 调色板结构 */
typedef struct
{
u8 B;
u8 G;
u8 R;
u8 A;
}BitmapARGB_TypeDef;
typedef struct
{
BitMapFileHeader_TypeDef FileHeader; /* 位图文件头 */
BitMapInfoHeader_TypeDef InfoHeader; /* 位图信息头 */
}BitMapInfo_TypeDef, * pBitMapInfo_TypeDef, * BitMapInfo_TypeDef_t;
/* FileSize : 可能和右键属性看到的不一样 */
/* ImgDataSize : 可能不对,ImgDataSize = FileSize - 54 - ColorPalette * 4 */
/* ImgDataOffset : 54 + ColorPalette * 4 */
#pragma pack()
序号 | 地址范围 | 名称 | 大小(Byte) | 说明 |
---|---|---|---|---|
1 | 0000~0001 | 文件标识 | 2 | 文件类别标识符,Windows下为"BM" |
2 | 0002~0005 | 文件大小 | 4 | 整个文件的大小,单位字节 |
3 | 0006~0007 | 保留1 | 2 | 保留1,默认为0 |
4 | 0008~0009 | 保留2 | 2 | 保留2,默认为0 |
5 | 000A~000D | 图像数据偏移地址 | 4 | 从文件开始到图像数据的偏移 |
6 | 000E~0011 | 信息头大小 | 4 | 位图信息头大小,Windows下为40 |
7 | 0012~0015 | 图像宽度 | 4 | 图像宽度,单位像素 |
8 | 0016~0019 | 图像高度 | 4 | 图像高度,单位像素 |
9 | 001A~001B | 颜色平面数 | 2 | 目标设备的平面数,必须为1 |
10 | 001C~001D | 像素位数 | 2 | 每像素的位数,必须为1、2、4、8、24、32 |
11 | 001E~0021 | 压缩类型 | 4 | 压缩类型,必须为0、1、2、3 |
12 | 0022~0025 | 图像数据大小 | 4 | 整个图像数据大小,单位字节,必须为4的倍数 |
13 | 0026~0029 | 水平分辨率 | 4 | 图像水平分辨率,单位像素/米 |
14 | 002A~002D | 垂直分辨率 | 4 | 图像垂直分辨率,单位像素/米 |
15 | 002E~0031 | 调色板大小 | 4 | 色彩表中颜色的索引数,有压缩才有调色板 |
16 | 0032~0035 | 重要颜色数 | 4 | 有压缩时与调色板大小相等,0表示都重要 |
17 | 0036~00xx | 调色板数据 | 4 * N | 调色板规范,每项用四字节ARGB表示,Byte0蓝色,Byte1绿色分量,Byte2红色分量,Byte3填充符(设置为0) |
18 | 00mm~00nn | 图像数据 | N | 该区域大小取决于压缩方式,包含图像所有数据,颜色数量和调色板索引 |
二、获取文件大小
/* 获取文件大小(单位字节) */
static u32 ulGetFileSize(const u8 * fileName)
{
struct stat fileSta = {
0};
u32 size = 0;
/* 打开文件 */
FILE *