日期:2014-05-16  浏览次数:20687 次

linux 平台camera得到YUV数据转RGB888及加BMP头文件

需要在Android平台上通过UVC得到纯YUV数据,需要验证数据的正确性。因此需要将每一帧的YUV数据转为RGB888,但纯的RGB888数据也无法在windows或者ubuntu上打开,需要加BMP头。此文章介绍其实现方法。

第一步:YUY2转为RGB888.

参考文章:

http://blog.csdn.net/jtujtujtu/article/details/3874621

//////////////////////////////////////////////////////////////////////////
// YUV2RGB
// pYUV			point to the YUV data
// pRGB			point to the RGB data
// width		width of the picture
// height		height of the picture
// alphaYUV		is there an alpha channel in YUV
// alphaRGB		is there an alpha channel in RGB
//////////////////////////////////////////////////////////////////////////
int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB)
{
	if (NULL == pYUV)
	{
		return -1;
	}
	unsigned char* pYUVData = (unsigned char *)pYUV;
	unsigned char* pRGBData = (unsigned char *)pRGB;
	if (NULL == pRGBData)
	{
		if (alphaRGB)
		{
			pRGBData = new unsigned char[width*height*4];
		}
		else
			pRGBData = new unsigned char[width*height*3];
	}
	int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
	int C1, D1, E1, C2;
	if (alphaRGB)
	{
		if (alphaYUV)
		{
			for (int i=0; i<height; ++i)
			{
				for (int j=0; j<width/2; ++j)
				{
					Y1 = *(pYUVData+i*width*3+j*6);
					U1 = *(pYUVData+i*width*3+j*6+1);
					Y2 = *(pYUVData+i*width*3+j*6+2);
					V1 = *(pYUVData+i*width*3+j*6+3);
					alpha1 = *(pYUVData+i*width*3+j*6+4);
					alpha2 = *(pYUVData+i*width*3+j*6+5);
					C1 = Y1-16;
					C2 = Y2-16;
					D1 = U1-128;
					E1 = V1-128;
					R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1;	
					*(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
					*(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
					*(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2;	
				}
			}	
		}
		else
		{
			int alpha = 255;
			for (int i=0; i<height; ++i)
			{
				for (int j=0; j<width/2; ++j)
				{
					Y1 = *(pYUVData+i*width*2+j*4);
					U1 = *(pYUVData+i*width*2+j*4+1);
					Y2 = *(pYUVData+i*width*2+j*4+2);
					V1 = *(pYUVData+i*width*2+j*4+3);
					C1 = Y1-16;
					C2 = Y2-16;
					D1 = U1-128;
					E1 = V1-128;
					R1 = ((298*C1 + 409*E1 + 128)>>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*4+j*8+3) = alpha;	
					*(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
					*(pRGBData+(he