实验要求:
在图像处理软件中自行生成多个BMP文件,至少含5个不同的场景画面。编写将第一步所生成的多个BMP文件转化为YUV文件,要求可在命令行中设置每个画面出现的帧数。最后形成的YUV文件应至少包含200帧。重点掌握函数定义、缓冲区分配、倒序读写、结构体的操作。 对整个程序进行调试,并将生成的YUV文件用播放软件观看,验证是否正确。
实验过程:
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
static float r0299[256],g0587[256],b0114[256],r01684[256],g03316[256],b05[256],r05[256],g04187[256],b00813[256];
void Table()
{
for(int i=0;i<256;i++) r0299[i]=0.299i;
for(int i=0;i<256;i++) g0587[i]=0.587i;
for(int i=0;i<256;i++) b0114[i]=0.114i;
for(int i=0;i<256;i++) r01684[i]=0.1684i;
for(int i=0;i<256;i++) g03316[i]=0.3316i;
for(int i=0;i<256;i++) b05[i]=0.5i;
for(int i=0;i<256;i++) r05[i]=0.5i;
for(int i=0;i<256;i++) g04187[i]=0.4187i;
for(int i=0;i<256;i++) b00813[i]=0.0813i;
}
int main( int argc,char** argv)
{
Table();
char filename_yuv,filename_rgb;
int framerate[4];
filename_yuv=argv[5];
for(int i=0;i<4;i++)
{
framerate[i]=atoi(argv[i+6]);
}
FILE fp_bmp,fp_yuv;
fp_yuv=fopen(filename_yuv,“wb”);
BITMAPFILEHEADER bmp_fileheader;
BITMAPINFOHEADER bmp_infoheader;
for(int i=0;i<4;i++)
{
unsigned char bmp_buffer;
unsigned char yuv_buffer;
unsigned char rgb_buffer;
unsigned char bmp_buffer_del,yuv_buffer_del,rgb_buffer_del;
fp_bmp=fopen(argv[i+1],“rb”);
fread(&bmp_fileheader,sizeof(BITMAPFILEHEADER),1,fp_bmp);
fread(&bmp_infoheader,sizeof(BITMAPINFOHEADER),1,fp_bmp);
int height,width,size,size_arc;
height=bmp_infoheader.biHeight;
width=bmp_infoheader.biWidth;
//size=bmp_fileheader.bfSize;
size_arc=heightwidth;
bmp_buffer=new unsigned char[size_arc3];
yuv_buffer=new unsigned char[size_arc3/2];
rgb_buffer=new unsigned char[size_arc3];
bmp_buffer_del=bmp_buffer;
yuv_buffer_del=yuv_buffer;
rgb_buffer_del=rgb_buffer;
fread(bmp_buffer,3sizeof(unsigned char),size_arc,fp_bmp);
for(int j=0;j<height;j++)
{
for(int k=0;k<width3;k=k+3)
{
rgb_buffer[jwidth3+k]=bmp_buffer[(height-1-j)width3+k];
rgb_buffer[jwidth3+k+1]=bmp_buffer[(height-1-j)width3+k+1];
rgb_buffer[jwidth*3+k+2]=bmp_buffer[(height-1-j)width3+k+2];
}
}
//RGB2YUV
unsigned char *b_buffer,*g_buffer,*r_buffer;
unsigned char *Y_buffer,*U_buffer,*V_buffer;
unsigned char *u_buffer,*v_buffer;
unsigned char *pu_up1,*pu_up2,*pv_up1,*pv_up2;
unsigned char *YUV__buffer,*RGB__buffer;
YUV__buffer=yuv_buffer;
RGB__buffer=rgb_buffer;
Y_buffer=YUV__buffer;
U_buffer=YUV__buffer+height*width;
V_buffer=YUV__buffer+height*width*5/4;
u_buffer=new unsigned char[height*width];
v_buffer=new unsigned char[height*width];
pu_up1=u_buffer;
pu_up2=u_buffer+width;
pv_up1=v_buffer;
pv_up2=v_buffer+width;
b_buffer=RGB__buffer;
g_buffer=RGB__buffer+1;
r_buffer=RGB__buffer+2;
unsigned char *pu_buffer,*pv_buffer;
pu_buffer=u_buffer;
pv_buffer=v_buffer;
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
if(r0299[*r_buffer]+g0587[*g_buffer]+b0114[*b_buffer]<0)
*Y_buffer=(unsigned char)0;
else
if(r0299[*r_buffer]+g0587[*g_buffer]+b0114[*b_buffer]>255)
*Y_buffer=(unsigned char)255;
else *Y_buffer=unsigned char (r0299[*r_buffer]+g0587[*g_buffer]+b0114[*b_buffer]);
if(-r01684[*r_buffer]-g03316[*g_buffer]+b05[*b_buffer]<-128)
*pu_buffer=(unsigned char)0;
else
if(-r01684[*r_buffer]-g03316[*g_buffer]+b05[*b_buffer]>128)
*pu_buffer=(unsigned char)255;
else *pu_buffer=unsigned char(-r01684[*r_buffer]-g03316[*g_buffer]+b05[*b_buffer]+128);
if(r05[*r_buffer]-g04187[*g_buffer]-b00813[*b_buffer]<-128)
*pv_buffer=(unsigned char)0;
else
if(r05[*r_buffer]-g04187[*g_buffer]-b00813[*b_buffer]>128)
*pv_buffer=(unsigned char)255;
else *pv_buffer=unsigned char(r05[*r_buffer]-g04187[*g_buffer]-b00813[*b_buffer]+128);
Y_buffer++;
pu_buffer++;
pv_buffer++;
r_buffer+=3;
g_buffer+=3;
b_buffer+=3;
}
}
for(int i=0;i<height/2;i++)
{
for(int j=0;j<width/2;j++)
{
*U_buffer=(*pu_up1+*(pu_up1+1)+*pu_up2+*(pu_up2+1))/4;
*V_buffer=(*pv_up1+*(pv_up1+1)+*pv_up2+*(pv_up2+1))/4;
U_buffer++;
V_buffer++;
pu_up1+=2;
pu_up2+=2;
pv_up1+=2;
pv_up2+=2;
}
if(i!=height/2)
{
pu_up1+=width;
pu_up2+=width;
pv_up1+=width;
pv_up2+=width;
}
}
delete[] u_buffer;
delete[] v_buffer;
for(int j=0;j<framerate[i];j++)
fwrite(yuv_buffer,sizeof(unsigned char),height*width*3/2,fp_yuv);
/*unsigned char *yuv_buffer_ori;
yuv_buffer_ori=yuv_buffer;
for(int j=0;j<framerate[i]-1;j++)
{
for(int k=0;k<size_arc*3/2;k++)
{
*(yuv_buffer+(size_arc*3/2))=*yuv_buffer;
yuv_buffer++;
}
}
fwrite(yuv_buffer_ori,sizeof(unsigned char),size_arc*3*framerate[i]/2,fp_yuv);*/
fclose(fp_bmp);
delete[] bmp_buffer_del;
delete[] yuv_buffer_del;
delete[] rgb_buffer_del;
}
fclose(fp_yuv);
return 0;
}