c 读取 24 bmp
场景:C读取24位BMP图像,该怎么解决
C读取24位BMP图像
写了个程序读取24位的BMP图像,程序如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
#define A 256
int main()
{
FILE *fp;
int n,dis;
int i,j,num=0,k=0;
int width,height;
unsigned char *r,*g,*b;
unsigned char **R,**G,**B;
unsigned char *temp;
if((fp=fopen("t.bmp","rb"))==NULL)
{
printf("Can't open file: a.bmp");
return 0;
}
fseek(fp,28,SEEK_SET);
fread(&n,2,1,fp);
printf("n=%d\n",n);
fseek(fp,18,SEEK_SET);
fread(&width,4,1,fp); /*图像宽*/
fseek(fp,22,SEEK_SET);
fread(&height,4,1,fp); /*图像高*/
printf("width=%d\n",width);
printf("height=%d\n",height);
fseek(fp,10,SEEK_SET);
fread(&dis,4,1,fp); /*文件头到图像数据的偏移量*/
printf("distance=%d\n",dis);
fseek(fp,dis,SEEK_SET);
if((r=(unsigned char *)malloc(width*height))==NULL)
{
printf("error \n");
exit(0);
}
if( (g=(unsigned char *)malloc(width*height))==NULL )
{
printf("error \n");
exit(0);
}
if((b=(unsigned char *)malloc(width*height))==NULL)
{
printf("error \n");
exit(0);
}
/*给R,G,B分配内存*/
if((R=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
R[i]=(unsigned char *)malloc(width);
if(R[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
if((G=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
G[i]=(unsigned char *)malloc(width);
if(G[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
if((B=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
B[i]=(unsigned char *)malloc(width);
if(B[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
/*一次性读取正确*/
if((temp=(unsigned char*)malloc(width*height*3))==NULL)
{
printf("error\n");
exit(0);
}
fread(temp,1,width*height*3,fp);
i=0;
k=0;
while(i<width*height*3)
{
b[k]=temp[i];
++i;
g[k]=temp[i];
++i ;
r[k]=temp[i];
++i;
++k;
}
k=0;
for(i=0;i<=height-1;++i)
{
for(j=0;j<width;++j)
{
R[height-1-i][j]=r[k*width+j];
G[height-1-i][j]=g[k*width+j];
B[height-1-i][j]=b[k*width+j];
}
++k;
}
printf("\n");
printf("display r(1)\n");
for(i=0;i<width*height;++i)
{
printf("%d ",r[i]);
++num;
if(num%width==0)
printf("\n");
}
printf("\n");
printf("display r(2)\n");
for(i=0;i<height;++i)
{
for(j=0;j<width;++j)
{
printf("%d ",R[i][j]);
}
printf("\n");
}
/*一个一个读取正确*/
/* while(1)
{
b[num]=fgetc(fp);
g[num]=fgetc(fp);
r[num]=fgetc(fp);
if(feof(fp))
{
break;
}
++num;
}
*/
/*num=0;
for(i=0;i<width*height;++i)
{
printf("%d ",r[i]);
++num;
if(num%width==0)
printf("\n");
}
*/
printf("k=%d",k);
fclose(fp);
free(r);
free(g);
free(b);
free(R);
free(G);
free(B);
free(temp);
printf("\n");
getch();
return 0;
}
结果用不同的编译器会出现不同的错误,用VC编译会出现内存出错。 用WinTC不会报错但是显示会出错,我尝试在VC中把最后的几个free注释掉几个,注释掉free(b)及后面的free函数就不会报错。请问是不是我的指针内存分配有什么不妥,麻烦帮我看下我的各个指针定义以及内存分配是否合理,请指教!!!
------解决方案--------------------
最好自己写两个结构体
一个是信息头,一个文件头
然后malloc这两个结构体
------解决方案--------------------
位图数据长度计算错误
if((temp=(unsigned char*)malloc(width*height*3))==NULL)
你可以通过位图头信息来获取位图数据的长度,从而得到需要分配空间的长度
实际上应该是这样计算的:
每行所占的字节数:lineByte=(width * 24+31)/32*4;
位图数据所占字节数:height * lineByte
------解决方案--------------------
是的,要考虑4字节对齐,而且也要考虑如果位图不是24位的格式。
C读取24位BMP图像
写了个程序读取24位的BMP图像,程序如下:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
#define A 256
int main()
{
FILE *fp;
int n,dis;
int i,j,num=0,k=0;
int width,height;
unsigned char *r,*g,*b;
unsigned char **R,**G,**B;
unsigned char *temp;
if((fp=fopen("t.bmp","rb"))==NULL)
{
printf("Can't open file: a.bmp");
return 0;
}
fseek(fp,28,SEEK_SET);
fread(&n,2,1,fp);
printf("n=%d\n",n);
fseek(fp,18,SEEK_SET);
fread(&width,4,1,fp); /*图像宽*/
fseek(fp,22,SEEK_SET);
fread(&height,4,1,fp); /*图像高*/
printf("width=%d\n",width);
printf("height=%d\n",height);
fseek(fp,10,SEEK_SET);
fread(&dis,4,1,fp); /*文件头到图像数据的偏移量*/
printf("distance=%d\n",dis);
fseek(fp,dis,SEEK_SET);
if((r=(unsigned char *)malloc(width*height))==NULL)
{
printf("error \n");
exit(0);
}
if( (g=(unsigned char *)malloc(width*height))==NULL )
{
printf("error \n");
exit(0);
}
if((b=(unsigned char *)malloc(width*height))==NULL)
{
printf("error \n");
exit(0);
}
/*给R,G,B分配内存*/
if((R=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
R[i]=(unsigned char *)malloc(width);
if(R[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
if((G=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
G[i]=(unsigned char *)malloc(width);
if(G[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
if((B=(unsigned char **)malloc(height))==NULL)
{
printf("error! \n");
exit(0);
}
for(i=0;i<height;++i)
{
B[i]=(unsigned char *)malloc(width);
if(B[i]==NULL)
{
printf("error! \n");
exit(0);
}
}
/*一次性读取正确*/
if((temp=(unsigned char*)malloc(width*height*3))==NULL)
{
printf("error\n");
exit(0);
}
fread(temp,1,width*height*3,fp);
i=0;
k=0;
while(i<width*height*3)
{
b[k]=temp[i];
++i;
g[k]=temp[i];
++i ;
r[k]=temp[i];
++i;
++k;
}
k=0;
for(i=0;i<=height-1;++i)
{
for(j=0;j<width;++j)
{
R[height-1-i][j]=r[k*width+j];
G[height-1-i][j]=g[k*width+j];
B[height-1-i][j]=b[k*width+j];
}
++k;
}
printf("\n");
printf("display r(1)\n");
for(i=0;i<width*height;++i)
{
printf("%d ",r[i]);
++num;
if(num%width==0)
printf("\n");
}
printf("\n");
printf("display r(2)\n");
for(i=0;i<height;++i)
{
for(j=0;j<width;++j)
{
printf("%d ",R[i][j]);
}
printf("\n");
}
/*一个一个读取正确*/
/* while(1)
{
b[num]=fgetc(fp);
g[num]=fgetc(fp);
r[num]=fgetc(fp);
if(feof(fp))
{
break;
}
++num;
}
*/
/*num=0;
for(i=0;i<width*height;++i)
{
printf("%d ",r[i]);
++num;
if(num%width==0)
printf("\n");
}
*/
printf("k=%d",k);
fclose(fp);
free(r);
free(g);
free(b);
free(R);
free(G);
free(B);
free(temp);
printf("\n");
getch();
return 0;
}
结果用不同的编译器会出现不同的错误,用VC编译会出现内存出错。 用WinTC不会报错但是显示会出错,我尝试在VC中把最后的几个free注释掉几个,注释掉free(b)及后面的free函数就不会报错。请问是不是我的指针内存分配有什么不妥,麻烦帮我看下我的各个指针定义以及内存分配是否合理,请指教!!!
------解决方案--------------------
最好自己写两个结构体
一个是信息头,一个文件头
然后malloc这两个结构体
------解决方案--------------------
位图数据长度计算错误
if((temp=(unsigned char*)malloc(width*height*3))==NULL)
你可以通过位图头信息来获取位图数据的长度,从而得到需要分配空间的长度
实际上应该是这样计算的:
每行所占的字节数:lineByte=(width * 24+31)/32*4;
位图数据所占字节数:height * lineByte
------解决方案--------------------
是的,要考虑4字节对齐,而且也要考虑如果位图不是24位的格式。