yuv420 转换成 bmp

源码如下:

// ConsoleApplication1.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <stdio.h>  
#include <stdlib.h> 

#define XSIZE 1920  
#define YSIZE 1080     

#define RGB_SIZE  XSIZE * YSIZE * 3
typedef unsigned char byte;


double YUV2RGB_CONVERT_MATRIX[3][3] = { { 1, 0, 1.4022 }, { 1, -0.3456, -0.7145 }, { 1, 1.771, 0 } };


void ConvertYUV2RGB(unsigned char *yuvFrame, unsigned char *rgbFrame, int width, int height)
{
	int uIndex = width * height;
	int vIndex = uIndex + ((width * height) >> 2);
	int gIndex = width * height;
	int bIndex = gIndex * 2;
	int temp, x, y;

	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			// R分量        
			temp = (int)(yuvFrame[y * width + x] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[0][2]);
			rgbFrame[y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
			// G分量       
			temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1][1] + (yuvFrame[vIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[1][2]);
			rgbFrame[gIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
			// B分量             
			temp = (int)(yuvFrame[y * width + x] + (yuvFrame[uIndex + (y / 2) * (width / 2) + x / 2] - 128) * YUV2RGB_CONVERT_MATRIX[2][1]);
			rgbFrame[bIndex + y * width + x] = (byte)(temp < 0 ? 0 : (temp > 255 ? 255 : temp));
		}
	}
}


int  main(){
	int i, j, y, x;
	long width, height;
	unsigned char *data;
	unsigned char *image;   //用于存放读取的yuv数据	
	unsigned char *image_bmp;

	FILE *fp_r;

	width = XSIZE;
	height = YSIZE;
	long int bytePerLine = width * 3;


	//申请空间
	image = (unsigned char *)malloc(width * height * 3 / 2);
	image_bmp = (unsigned char *)malloc(width * height * 3);
	data = (unsigned char*)malloc(bytePerLine * height);


	if ((NULL == image) || (image_bmp == NULL) || (data == NULL))
	{
		printf("faied to malloc the image\n");
		return -1;
	}



	/********读取yuv 文件***********/
	fp_r = fopen("test.yuv", "rb"); //打开yuv 文件
	if (NULL == fp_r)
	{
		printf("failed to open the fp_r\n");
		return -1;
	}

	fread(image, sizeof(unsigned char), XSIZE * YSIZE * 3 / 2, fp_r);
	fclose(fp_r);





	for (i = 0; i<width *height * 3; i++)
		*(image_bmp + i) = 255;


	//写bmp图片
	int gIndex = width * height;
	int bIndex = gIndex * 2;

	unsigned char header[54] = {
		0x42, 0x4d,       //WORD  bfType----------- [0,1]   
		0, 0, 0, 0,      //DWORD bfSize----------- [2,3,4,5]   
		0, 0,            //WORD  bfReserved1------ [6,7]   
		0, 0,            //WORD  bfReserved2------ [8,9]   
		54, 0, 0, 0,      //WORD  bfOffBits-------- [10,11,12,13]   

		40, 0, 0, 0,      //DWORD biSize----------- [14,15,16,17]   
		0, 0, 0, 0,      //LONG  biWidth---------- [18,19,20,21]    
		0, 0, 0, 0,      //LONG  biHeight--------- [22,23,24,25]    
		1, 0,            //WORD  biplanes--------- [26,27]   
		24, 0,            //WORD  biCount---------- [28,29]   
		0, 0, 0, 0,      //DWORD biCompression---- [30,31,32,33]   
		0, 0, 0, 0,      //DWORD biSizeImage------ [34,35,36,37]   
		0, 0, 0, 0,      //LONG  biXPelsPerMeter-- [38,39,40,41]   
		0, 0, 0, 0,      //LONG  biYPelsPerMeter-- [42,43,44,45]    
		0, 0, 0, 0,      //DWORD biClrUsed-------- [46,47,48,49]    
		0, 0, 0, 0       //DWORD biClrImportant--- [50,51,52,53]   
	};
	long file_size = (long)width * (long)height * 3 + 54;
	header[2] = (unsigned char)(file_size & 0x000000ff);
	header[3] = (file_size >> 8) & 0x000000ff;
	header[4] = (file_size >> 16) & 0x000000ff;
	header[5] = (file_size >> 24) & 0x000000ff;

	header[18] = width & 0x000000ff;
	header[19] = (width >> 8) & 0x000000ff;
	header[20] = (width >> 16) & 0x000000ff;
	header[21] = (width >> 24) & 0x000000ff;

	header[22] = height & 0x000000ff;
	header[23] = (height >> 8) & 0x000000ff;
	header[24] = (height >> 16) & 0x000000ff;
	header[25] = (height >> 24) & 0x000000ff;


	char filename[6] = "1.bmp";




	ConvertYUV2RGB(image, image_bmp, width, height);

	for (y = height - 1, j = 0; y >= 0; y--, j++)
	{
		for (x = 0, i = 0; x < width; x++)
		{
			data[y * bytePerLine + i++] = image_bmp[bIndex + j * width + x];
			// B                    

			data[y * bytePerLine + i++] = image_bmp[gIndex + j * width + x];
			// G          

			data[y * bytePerLine + i++] = image_bmp[j * width + x];
			// R          
		}
	}
	//sprintf(filename, "%d.bmp",1);   


	FILE *fp_w;
	if (!(fp_w = fopen(filename, "wb")))
		return -1;

	fwrite(header, sizeof(unsigned char), 54, fp_w);

	fwrite(data, sizeof(unsigned char), XSIZE * YSIZE * 3, fp_w);

	fclose(fp_w);
	free(image);
	return(0);
}

posted @ 2019-07-02 10:37  youngliu91  阅读(1646)  评论(0编辑  收藏  举报