通过命令行传递文件路径参数,输出BMP的width、height、size
1、从BMP的结构信息可知,文件大小、图片宽度、图片高度均占据4个字节,所以只需要打开文件读取对应位置的信息并打印即可。
2、为了提高可移植性,可以定义结构体,保持和BMP文件结构一致,这样可以一次性读取保存,方便后续调用。但是定义结构体时注意字节对齐,否则系统可能分配更多的空间,这样读取的信息会出现错误。
实现代码
/****************************************************************************
*
* file name: 2024-05-11_GetBMPInfo.c
* author : [email protected]
* date : 2024-05-11
* function : 获取BMP图片信息。
* note : 参考:https://learn.microsoft.com/en-us/previous-versions/ms969901(v=msdn.10)?redirectedfrom=MSDN
* CopyRight (c) 2024 [email protected] Right Reseverd
*
****************************************************************************/
#include <stdio.h>
#pragma pack(1) //将字节对齐改为1byte
//定义BMP文件头结构体
struct BITMAPFILEHEADER
{
char bfType[2]; //一定是‘BM’
int bfSize; //文件大小
short bfReserved1; //保留
short bfReserved2; //保留
int bfOffBits; //指定从 BITMAPFILEHEADER 结构的开头到实际位的开头的偏移量
};
//定义BMP信息头结构体
struct BITMAPINFOHEADER
{
int biSize; //应设置为 sizeof(BITMAPINFOHEADER)。该字段定义标题的大小(减去颜色表)。
int biWidth; //位图的宽度(以像素为单位)
int biHeight; //位图的高度(以像素为单位)
short biPlanes; //应始终为 1
short biBitCount; //DIB 的颜色分辨率(以每像素位数为单位)。该字段只有四个值有效:1、4、8 和 24。将来可能会添加新的分辨率(例如 16 位),但目前只有这四个值定义有效的 DIB。
int biCompression; //指定压缩类型。可以是以下三个值之一:BI_RGB、BI_RLE4 或 BI_RLE8。
int biSizeImage; //包含位图本身的大小(以字节为单位)或值 0。值 0 表示 DIB 具有默认大小。
int biXPelsPerMeter; //为所需的位图尺寸定义应用程序指定的值。此信息可用于在不同分辨率的设备上维护图像的物理尺寸。 GDI从不触及这些领域。不填时,均设置为0。
int biYPelsPerMeter; //为所需的位图尺寸定义应用程序指定的值。此信息可用于在不同分辨率的设备上维护图像的物理尺寸。 GDI从不触及这些领域。不填时,均设置为0。
int biClrUsed; //当该字段设置为 0 时,颜色表中的颜色数量基于 biBitCount 字段(1 表示 2 种颜色,4 表示 16 种,8 表示 256 种,24 表示无颜色表)。
int biClrImportant; //指定颜色表的前 x 颜色对 DIB 很重要。如果其余颜色不可用,图像仍然以可接受的方式保留其含义。
};
#pragma pack() //将字节对齐恢复默认
int main(int argc, char const *argv[])
{
//1.BMP图片的路径是通过命令行传递,所以需要检测参数有效性
if ( 2 != argc )
{
printf("argument is invaild\n");
return -1;
}
//2.利用标准IO库fopen()打开BMP文件
FILE *BMP_file = fopen(argv[1], "rb");
if ( NULL == BMP_file)
{
printf("open %s is error\n",argv[1]);
return -1;
}
//定义3个变量保存需要获取的信息
int bfSize;
int biWidth;
int biHeight;
//偏移2个字节,读取4个字节获得文件大小信息
fseek(BMP_file, 2, SEEK_SET);
fread(&bfSize, 4, 1, BMP_file);
//偏移18字节,读取4个字节获得宽度信息
fseek(BMP_file, 18, SEEK_SET);
fread(&biWidth, 4, 1, BMP_file);
//偏移22字节,读取4个字节获得宽度信息
fseek(BMP_file, 22, SEEK_SET);
fread(&biHeight, 4, 1, BMP_file);
//输出信息
printf("bmp name is %s, width = %d, height = %d, size = %d\n", argv[1], biWidth, biHeight, bfSize);
//定义文件头、信息头变量
struct BITMAPFILEHEADER BiFHead;
struct BITMAPINFOHEADER BiInfoHead;
//读取BMP信息直接写入结构体中
fseek(BMP_file, 0, SEEK_SET);
fread(&BiFHead, 14, 1, BMP_file);
fread(&BiInfoHead, 40, 1, BMP_file);
printf("bmp name is %s, width = %d, height = %d, size = %d\n", argv[1], BiInfoHead.biWidth, BiInfoHead.biHeight, BiFHead.bfSize);
return 0;
}