C语言 24位真彩色bmp图像按字节读取多出一个字节

用c语言读取24位真彩色图像时,我想按unsigned char读取,将所有数据读取到一个一维数组里。但是会出现某些行会莫名其妙多出一个数字是什么问题?比如我如下的程序:

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define BFTYPE 0
#define BFSIZE 2
#define BFOFFBITS 10
#define BISIZE 13
#define BIWIDTH 17
#define BIHEIGHT 21
#define BIBITCOUNT 27
#define BISIZEIMAGE 33

void main(){
FILE *fp1,*fp2;
unsigned char *image,image_temp;
unsigned char fileheader[54],*header;
unsigned long int width,height,data_add,width_temp;
int i,j;

fp1=fopen("lena.bmp","rb");
fp2=fopen("newfile.bmp","w");
fread(&fileheader,1,54,fp1);

data_add=((fileheader[BFOFFBITS+3]*16+fileheader[BFOFFBITS+2])*16+fileheader[BFOFFBITS+1])*16+fileheader[BFOFFBITS];
width=((fileheader[BIWIDTH+3]*16+fileheader[BIWIDTH+2])*16+fileheader[BIWIDTH+1])*16+fileheader[BIWIDTH+0];
height=((fileheader[BIHEIGHT+3]*16+fileheader[BIHEIGHT+2])*16+fileheader[BIHEIGHT+1])*16+fileheader[BIHEIGHT+0];

width_temp=(int)ceil((double)width*3/4);
image=(unsigned char*)malloc(width_temp*4*sizeof(unsigned char));
header=(unsigned char*)malloc(data_add*sizeof(unsigned char));

fseek(fp1,0,SEEK_SET);

fread(header,1,data_add,fp1);
fread(image,1,width_temp*4,fp1);

fwrite(header,1,data_add,fp2);
fwrite(image,1,width_temp*4,fp2);
fclose(fp1);fclose(fp2);
return;

}
我只是保存第一行数据,然而第一行数据就会在0x121的位置上多出一个0x0D……这是为什么呢?是程序哪里错了还是编译器存储结构的问题么?应该怎么改?
PS:我只是想编一个适用于任意大小和任意颜色位数的bmp图像处理程序,而且关键是还要做到每行字节数都是4的倍数……我原来用的是三个字节组成的像素结构,这样如果宽度是一些奇怪的数的时候,就需要在每一行的后面补1个字节或者2个字节,而不是补一个完整的像素结构,这个时候我原来用结构的方法就不适用了,所以我才想改成一维的数组。
求大神解惑orz

你想把每行字节变成4的倍数,但你目前的程序没法实现这一点。
你的width_temp是这样设置的:width_temp=(int)ceil((double)width*3/4);
后面是这么用的:fread(image,1,width_temp*4,fp1);
仔细看,你只是把width*3/4*4,这样做没有意义,反而平白无故损失了精度,因为在除以4的过程中,小数部分会被舍弃。

如果你想遍一个适用于任意大小和任意颜色位数的bmp图像处理程序,并且你还希望以行为单位进行图像处理,
该4字节对齐就对齐,修改你的结构吧。追问

并没有损失精度啊,我明明用了ceil函数,所以((int)ceil((double)width*3/4))*4就是不小于每一行宽度且是4的倍数的值啊。

而且如何以行为单位进行处理?

追答

好吧,我没留意ceil函数。使用ceil函数的话,不会舍弃小数部分而是直接进位了。
不过,你这样处理,如果图像的宽度不能被4整除,那么在行的结尾就会多出一个字节,这是使用ceil函数的副作用。

追问

本来就应该是这样啊……如果图像每一行的字节数不是4的倍数,就必须用0补齐为4的倍数……不然会出错,我试过,做出来的图像根本看不了。

温馨提示:答案为网友推荐,仅供参考
相似回答