关于 bmp图片存储中的字节对齐问题

1. bmp数据对齐问题。

假设所读取的bmp图片位数是24,图像高度和宽度分别为998像素和726像素,每个像素占3个字节,即每行像素占3*726个字节,不是4的整数倍,首先需要对每行字节进行补零操作。假设文件头和信息头分别为bfh和bih,则每行所补的字节数为:

offset_bytes = 4 - (bih.biWidth * bih.biBitCount/8)%4

补齐后每行所占的字节数为:

row_length = 4*((bih.biWidth * bih.biBitCount + 31)/32)

注意上式中的4不能和分母中的32约掉,还有4后面紧跟的括号不能省去,否则会失去求整的效果。

加上31的作用是:当图片每行所占字节是4的整数倍数,31由于取整忽略掉,否则31起到进位作用。

2. 图片数据区字节读取问题。

在理解bmp图片的4字节对齐原理后,下来分析数据区字节读取问题。对于24位bmp图,每个像素占3个字节,读到每行末尾换行读取时,需要跳过offset_bytes个字节,采用fseek函数实现,其原型是:int fseek( FILE *stream, long offset, int origin );

1). 参数1 stream:文件结构指针。

2). 参数1 offset:偏移字节数,即跳过的字节数目。

3). 参数1 origin:计算偏移字节的起始位置。有三个选项:

a). SEEK_CUR:从当前位置计算;

b). SEEK_END:从文件末尾开始计算;

c). SEEK_SET:从文件开头计算;

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C语言,处理BMP图片需要了解BMP文件的格式和结构。BMP文件由文件头、位图信息头和像素数据组成,其文件头和位图信息头包含了BMP文件的基本信息,而像素数据则是BMP文件真正存储图像信息的部分。 下面是一个简单的读取BMP文件的例子: ```c #include <stdio.h> #include <stdlib.h> #pragma pack(push, 1) // 确保按照1字节对齐 typedef struct { unsigned short bfType; // 文件类型 unsigned int bfSize; // 文件大小 unsigned short bfReserved1; // 保留字节 unsigned short bfReserved2; // 保留字节 unsigned int bfOffBits; // 像素数据偏移量 } BMPFileHeader; typedef struct { unsigned int biSize; // 信息头大小 int biWidth; // 图像宽度 int biHeight; // 图像高度 unsigned short biPlanes; // 颜色平面数 unsigned short biBitCount; // 每个像素的位数 unsigned int biCompression; // 压缩类型 unsigned int biSizeImage; // 像素数据大小 int biXPelsPerMeter; // 水平分辨率 int biYPelsPerMeter; // 垂直分辨率 unsigned int biClrUsed; // 使用的颜色数 unsigned int biClrImportant; // 重要颜色数 } BMPInfoHeader; #pragma pack(pop) int main() { FILE *fp = fopen("test.bmp", "rb"); if (fp == NULL) { printf("Failed to open file!\n"); return -1; } BMPFileHeader fileHeader; BMPInfoHeader infoHeader; fread(&fileHeader, sizeof(BMPFileHeader), 1, fp); fread(&infoHeader, sizeof(BMPInfoHeader), 1, fp); int width = infoHeader.biWidth; int height = infoHeader.biHeight; int bitCount = infoHeader.biBitCount; int lineByte = (width * bitCount + 31) / 32 * 4; // 每行像素所占字节数,4字节对齐 unsigned char *data = (unsigned char *)malloc(lineByte * height); fseek(fp, fileHeader.bfOffBits, SEEK_SET); fread(data, lineByte * height, 1, fp); fclose(fp); // 处理像素数据 // ... free(data); return 0; } ``` 在上面的例子,我们首先定义了BMP文件头和位图信息头的结构体,并使用#pragma pack指令将结构体按照1字节对齐,确保结构体的大小和BMP文件的格式一致。然后我们使用fopen函数打开BMP文件,并依次读取文件头和位图信息头,得到图像的宽度、高度、每个像素的位数等信息。接着根据图像的宽度、高度和每个像素的位数计算出每行像素所占的字节数,然后使用malloc函数动态分配内存,读取像素数据。最后我们可以对像素数据进行处理,如修改像素值、转换颜色空间等操作。 需要注意的是,在处理BMP文件时,如果像素数据的宽度不是4的倍数,则需要在每行像素数据后面添加一些填充字节,使得每行像素数据的总字节数是4的倍数。这样做是为了使像素数据在内存的布局符合CPU的要求,提高读取速度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值