基于C语言的BMP文件格式转换

//将bmp图片文件保存于1.bmp中,若图片是bmp文件,则在out.bmp文件中可以看到,若不是,则在out.bmp中显示打开失败。
//识别乒乓球
#include<stdio.h>
#include<stdlib.h>


//此bmp文件图像深度要求24bit
#define BM 19778  //BM对应的asc码0x4d42转为10进制
#define BITMAPFILEHEADERLENGTH 14  // The bmp FileHeader length is 14
void BmpFILEtest(FILE* fpbmp);//测试是否为bmp文件 
void BmpHeaderPartLength(FILE* fpbmp);//获得从位图头到位图详细数据部分的offset
void BmpWidthHeight(FILE* fpbmp);//获得bmp文件的宽度和高度信息 
void BmpDataPart(FILE* fpbmp);//获得调色板的rgb数据
void Bmpoutput(FILE *fpout);//输出与txt文件相符的bmp图像


unsigned int offset=0;//offset定义为数据的起始地址
long width;
long height;
unsigned char r[2000][2000],output_r[2000][2000];
unsigned char g[2000][2000],output_g[2000][2000];
unsigned char b[2000][2000],output_b[2000][2000];
unsigned char num=0;






int main()
{
unsigned char *fp_temp;
FILE *fpbmp;
FILE *fpout;


fpbmp=fopen("1.bmp","rb");  //打开1.bmp文件


if(fpbmp==NULL)
{
printf("打开bmp文件失败!!!\n");
return 1;
}
if((fpout=fopen("out.bmp","wb"))==NULL)
{
printf("打开out.bmp文件失败!!!\n");
return 1;
}
BmpFILEtest(fpbmp); //测试是否为bmp文件
BmpHeaderPartLength(fpbmp);//得到bmp文件的首地址区
BmpWidthHeight(fpbmp);//得到bmp文件的高度和宽度

fseek(fpbmp,0L,SEEK_SET);
fseek(fpout,0L,SEEK_SET);


fp_temp=(unsigned char*)malloc(offset*sizeof(unsigned char));
fread(fp_temp,1,offset,fpbmp);
fwrite(fp_temp,1,offset,fpout);


BmpDataPart(fpbmp);//将数据保存在文件中
/*
//对图片进行处理


  */


Bmpoutput(fpout);//转化为bmp文件


fclose(fpbmp);
fclose(fpout);  //关闭文件

printf("图片中乒乓球的个数为%d个。\n",num+1);
return 0;



 } 
 
void BmpFILEtest(FILE* fpbmp)   
{
unsigned short bftybe=0;
fseek(fpbmp,0L,SEEK_SET);  //fseek将位置指针移到指定位置(文件起始) 
fread(&bftybe,sizeof(char),2,fpbmp);//读取fpbmp文件中的前两个字节到bftybe中
if(BM!=bftybe)
{
printf("This file is not bmp file!!!\n");
exit(1);
}
}


void BmpHeaderPartLength(FILE* fpbmp)
{
fseek(fpbmp,10L,SEEK_SET);
fread(&offset,sizeof(char),4,fpbmp);
printf("The header part is of length %d.\n",offset);

}


void BmpWidthHeight(FILE* fpbmp)
{
fseek(fpbmp,18L,SEEK_SET);
fread(&width,sizeof(char),4,fpbmp);
fseek(fpbmp,22L,SEEK_SET);
fread(&height,sizeof(char),4,fpbmp);
printf("The width of the bmp file is %ld.\n",width);
printf("The height of the bmp file is %ld.\n",height);
}


void BmpDataPart(FILE* fpbmp)
{
int i,j=0;
int stride;//储存图像数据每行的字节个数
unsigned char *pix=NULL; //储存像素到pix中
FILE *fpr;
FILE *fpg;
FILE *fpb;
if((fpr=fopen("bmpr.txt","w+"))==NULL)
{
printf("Failed to construct file bmpr.txt");
exit(1);
}
if((fpg=fopen("bmpg.txt","w+"))==NULL)
{
printf("Failed to construct file bmpg.txt");
exit(1);
}
if((fpb=fopen("bmpb.txt","w+"))==NULL)
{
printf("Failed to construct file bmpb.txt");
exit(1);
}
fseek(fpbmp,offset,SEEK_SET);
stride=(24*width+31)/8;
stride=stride/4*4;
pix=(unsigned char*)malloc(stride*sizeof(unsigned char));  //动态分配像素大小 


for(j=0;j<height;j++)  
{
fread(pix,1,stride,fpbmp);//读取fpbmp中的stride个数据,每个数据读一个字节,到pix中
for(i=0;i<width;i++)
{
r[height-1-j][i]=pix[i*3+2];
g[height-1-j][i]=pix[i*3+1];
b[height-1-j][i]=pix[i*3];  //顺序为b g r,从下到上,从左到右扫描

output_r[height-1-j][i]=pix[i*3+2];
output_g[height-1-j][i]=pix[i*3+1];
output_b[height-1-j][i]=pix[i*3];


}
}


for(i=0;i<height;i++)
{
for(j=0;j<width-1;j++)
{
fprintf(fpb,"%4d",b[i][j]);
fprintf(fpg,"%4d",g[i][j]);
fprintf(fpr,"%4d",r[i][j]);
}
}


fclose(fpr);
fclose(fpg);
fclose(fpb);


}


void Bmpoutput(FILE* fpout)
{
int i,j;
int stride;
unsigned char* pixout=NULL;


stride=(24*width+31)/8;
stride=stride/4*4;
pixout=(unsigned char*)malloc(stride*sizeof(unsigned char));


fseek(fpout,offset,SEEK_SET);


for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
//通过RGB值判断是否为黄色,如果不是则将其变为黑色,
// if((output_b[height-1-j][i]<=100)&&(output_g[height-1-j][i]>=100)&&(output_g[height-1-j][i]<=200)&&(output_r[height-1-j][i]>200))
// {
// }
// else
// {
// output_b[height-1-j][i]=0;
// output_g[height-1-j][i]=0;
// output_r[height-1-j][i]=0;
// }
pixout[i*3+2]=output_r[height-1-j][i];
pixout[i*3+1]=output_g[height-1-j][i];
pixout[i*3]  =output_b[height-1-j][i];
}
fwrite(pixout,1,stride,fpout);
}


}

猜你喜欢

转载自blog.csdn.net/weixin_42264284/article/details/80457512
今日推荐