一、实验原理
1、BMP图像文件格式
位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。BMP位图文件默认的文件扩展名是bmp或者dib。
BMP文件大体上分为四个部分:
2、文件头结构体函数
typedef struct tagBITMAPFILEHEADER {
WORD bfType; /* 说明文件的类型 /
DWORD bfSize; / 说明文件的大小,用字节为单位 */
/注意此处的字节序问题
WORD bfReserved1; / 保留,设置为0 /
WORD bfReserved2; / 保留,设置为0 /
DWORD bfOffBits; / 说明从BITMAPFILEHEADER结构
开始到实际的图像数据之间的字节偏移量 */
} BITMAPFILEHEADER;
3、文件信息结构体函数
typedef struct tagBITMAPINFOHEADER {
DWORD biSize; /* 说明结构体所需字节数 /
LONG biWidth; / 以像素为单位说明图像的宽度 /
LONG biHeight; / 以像素为单位说明图像的高度*/
WORD biPlanes; /* 说明位面数,必须为1 /
WORD biBitCount; / 说明位数/像素,1、2、4、8、24 /
DWORD biCompression; / 说明图像是否压缩及压缩类型
BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS /
DWORD biSizeImage; / 以字节为单位说明图像大小 ,必须是4的
整数倍*/
LONG biXPelsPerMeter; /* 目标设备的水平分辨率,像素/米 */
LONG biYPelsPerMeter; /*目标设备的垂直分辨率,像素/米 /
DWORD biClrUsed; / 说明图像实际用到的颜色数,如果为0
则颜色数为2的biBitCount次方 */
DWORD biClrImportant; /说明对图像显示有重要影响的颜色
索引的数目,如果是0,表示都重要。/
} BITMAPINFOHEADER;
二、实验思路
首先读取BMP文件,调用函数读取BMP文件的RGB信息,再调用RGB转YUV函数,将RGB转为YUV,最后写入YUV文件。
三、实验代码
1、主函数
#include <stdio.h>
#include <windows.h>
#include "bmp2yuv.h"
void main(int argc, char *argv[])
{
FILE *bmpFile = NULL, *yuvFile = NULL;
BITMAPFILEHEADER File_header;
BITMAPINFOHEADER Info_header;
char* bmpFileName=NULL;
char* yuvFileName=NULL;
unsigned char * rgbBuf = NULL;
unsigned char * yBuff = NULL;
unsigned char * uBuff = NULL;
unsigned char * vBuff = NULL;
int flip = 0;//flip=1时正序,为0时上下翻转
int frame_count = 250;//每图50帧,1bit,4bit,8bit,16bit,24bit各一张,共250帧
int frame_width, frame_height;
//打开yuv文件
yuvFileName=argv[6];
if ((yuvFile = fopen(yuvFileName, "wb")) == NULL)
{
printf("yuv file failed!");
exit(0);
}
else
{
printf("The output yuv file is %s\n",yuvFileName);
}
for (int n = 1; n < 6; n++)
{
// 循环打开bmp文件
if ((bmpFile = fopen(argv[n], "rb")) == NULL)
{
printf("bmp file open failed!");
exit(0);
}
else
{
printf("The input bmp file is %s\n",bmpFileName);
}
// 读文件头信息
if (fread(&File_header, sizeof(BITMAPFILEHEADER), 1, bmpFile) != 1)
{
printf("read file header error!");
exit(0);
}
//判断是否为bmp文件
if (File_header.bfType != 0x4D42)
{
printf("Not bmp file!");
exit(0);
}
//读信息头信息
if (fread(&Info_header, sizeof(BITMAPINFOHEADER), 1, bmpFile) != 1)
{
printf("read info header error!");
exit(0);
}
frame_width = Info_header.biWidth;
frame_height=Info_header.biHeight;
printf("This is a %d bits image!\n", Info_header.biBitCount);
printf("\nbmp size: \t%d X %d\n", Info_header.biWidth, Info_header.biHeight);
//开辟缓冲区
rgbBuf = (unsigned char *)malloc(frame_height*frame_width * 3);
memset(rgbBuf, 0, frame_height*frame_width * 3);//初始化函数,用于清0
yBuff = (unsigned char *)malloc(frame_height*frame_width);
uBuff = (unsigned char *)malloc((frame_height*frame_width) / 4);
vBuff = (unsigned char *