基於C語言的BMP檔案格式轉換
阿新 • • 發佈:2019-01-24
//將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);
}
}
//識別乒乓球
#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);
}
}