色彩空间转换

1. http://blog.csdn.net/yyingwei/article/details/22649575

//以下是yv12到RGB24的转换算法,如果是yuv420到RGB24转换,秩序u,v反过来就可以了。
//即:
// unsigned char* uData = &yData[nYLen];
// unsigned char* vData = &vData[nYLen>>2];
<pre name="code" class="cpp">bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight)
{
	if(!pYV12 || !pRGB24)
		return false;

	const long nYLen = long(iHeight * iWidth);
	const int nHfWidth = (iWidth>>1);

	if(nYLen < 1 || nHfWidth < 1) 
		return false;

	unsigned char* yData = pYV12;
	unsigned char* vData = &yData[nYLen];
	unsigned char* uData = &vData[nYLen>>2];
	if(!uData || !vData)
		return false;

	int rgb[3];
	int i, j, m, n, x, y;
	m = -iWidth;
	n = -nHfWidth;
	for(y = 0; y < iHeight; y++)
	{
		m += iWidth;

		if(!(y % 2))
			n += nHfWidth;

		for(x=0; x < iWidth; x++)
		{
			i = m + x;
			j = n + (x>>1);
			rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值
			rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128)  - 0.703125 * (vData[j] - 128)); // g分量值
			rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值
			j = nYLen - iWidth - m + x;
			i = (j<<1) + j;
			for(j=0; j<3; j++)
			{
				if(rgb[j]>=0 && rgb[j]<=255)
					pRGB24[i + j] = rgb[j];
				else
					pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255;
			}
		}
	}

	return true;
}

 

2

#include "stdio.h"

#define  ALIGNMENTTO16(size) (((size) + 15) / 16 * 16)
void UYVYtoYV12(unsigned char* UYVYBuffer, 
                int ImageWidth, 
                int ImageHeight,
                unsigned char* YBuffer, 
                unsigned char* UBuffer, 
                unsigned char* VBuffer, 
                int SrcPitch, 
                int DstPitch)
{
   unsigned char* pDestY = YBuffer;
   unsigned char* pDestU = UBuffer;
   unsigned char* pDestV = VBuffer;
   int i;
   int j;

   //  For each destination U and V pixel
   for (i = 0; i < ImageHeight / 2; ++i)
   {
      for (j = 0; j < ImageWidth / 2; ++j)
      {
         int u;
         int v;

         //  Subsample U
         u = UYVYBuffer[j * 4];
         u += UYVYBuffer[j * 4 + SrcPitch];
         u /= 2;
         pDestU[j] = u;

         //  Subsample V
         v = UYVYBuffer[j * 4 + 2];
         v += UYVYBuffer[j * 4 + 2 + SrcPitch];
         v /= 2;
         pDestV[j] = v;

         //  Copy Y
         pDestY[j * 2] = UYVYBuffer[j * 4 + 1];
         pDestY[j * 2 + 1] = UYVYBuffer[j * 4 + 3];
         pDestY[DstPitch + j * 2] = UYVYBuffer[j * 4 + SrcPitch + 1];
         pDestY[DstPitch + j * 2 + 1] = UYVYBuffer[j * 4 + SrcPitch + 3];
      }

      pDestY += DstPitch * 2;  //  Step 2 Y rows
      pDestU += DstPitch / 2;  //  Step 1 U row
      pDestV += DstPitch / 2;  //  Step 1 V row
      UYVYBuffer += SrcPitch * 2;  //  Step 2 source rows
   }

   return;
}

void YUY2toYV12(unsigned char* YUY2Buffer, 
                int ImageWidth, 
                int ImageHeight,
                unsigned char* YBuffer, 
                unsigned char* UBuffer, 
                unsigned char* VBuffer, 
                int SrcPitch, 
                int DstPitch)
{
   unsigned char* pDestY = YBuffer;
   unsigned char* pDestU = UBuffer;
   unsigned char* pDestV = VBuffer;
   int i;
   int j;

   //  For each destination U and V pixel
   for (i = 0; i < ImageHeight / 2; ++i)
   {
      for (j = 0; j < ImageWidth / 2; ++j)
      {
         int u;
         int v;

         //  Subsample U
         u = YUY2Buffer[j * 4 + 1];
         u += YUY2Buffer[j * 4 + 1 + SrcPitch];
         u /= 2;
         pDestU[j] = u;

         //  Subsample V
         v = YUY2Buffer[j * 4 + 3];
         v += YUY2Buffer[j * 4 + 3 + SrcPitch];
         v /= 2;
         pDestV[j] = v;

         //  Copy Y
         pDestY[j * 2] = YUY2Buffer[j * 4];
         pDestY[j * 2 + 1] = YUY2Buffer[j * 4 + 2];
         pDestY[DstPitch + j * 2] = YUY2Buffer[j * 4 + SrcPitch];
         pDestY[DstPitch + j * 2 + 1] = YUY2Buffer[j * 4 + SrcPitch + 2];
      }

      pDestY += DstPitch * 2;  //  Step 2 Y rows
      pDestU += DstPitch / 2;  //  Step 1 U row
      pDestV += DstPitch / 2;  //  Step 1 V row
      YUY2Buffer += SrcPitch * 2;  //  Step 2 source rows
   }

   return;
}

void YVYUtoYV12( unsigned char *src, 
                int ImageWidth, 
                int ImageHeight,
                unsigned char *YBuffer, 
                unsigned char *UBuffer, 
                unsigned char *VBuffer, 
                int SrcPitch,
                int DstPitch )
{
    int i,j;

    unsigned char *YDst=YBuffer;
    unsigned char *UDst=UBuffer;
    unsigned char *VDst=VBuffer;

    // for each destination u and v pixel
    for(i=0;i<ImageHeight/2;i++)
    {
        for(j=0;j<ImageWidth/2;j++)
        {
            int u,v;

            // subsample u
            u = src[j*4+3];
            u +=src[j*4+3+SrcPitch];
            u /= 2;
            UDst[j] = u ;

            // subsample v
            v = src[j*4+1];
            v += src[j*4+1+SrcPitch];
            v /= 2;
            VDst[j] = v;

            // calculate the 4 y's
            YDst[j*2] = src[j*4];
            YDst[j*2+1] = src[j*4+2];
            YDst[DstPitch + j*2] = src[j*4+SrcPitch];
            YDst[DstPitch + j*2 + 1] = src[j*4+SrcPitch + 2];

        }
        YDst+=DstPitch*2;   // step 2 y rows
        UDst+=DstPitch/2;   // step 1 u row
        VDst+=DstPitch/2;   // step 1 v row
        src+=SrcPitch*2; // step 2 source rows
    }
}

void main()
{
   //待转换数据和宽高
   LPBYTE SrcBuffer = ?;
   int width = ?;
   int height = ?;

   int YV12BufferSize = ALIGNMENTTO16(width * 3 / 2) * height;
   LPBYTE YV12Buffer = new BYTE[YV12BufferSize]();

   LPBYTE pY = YV12Buffer;
   LPBYTE pV = pY + width * height;
   LPBYTE pU = pV + width * height / 4;
   
   int SrcPitch = ALIGNMENTTO16(width) * 2;
   int DstPitch = ALIGNMENTTO16(width);

   // UYYV to YV12
   UYVYtoYV12(SrcBuffer, 
      width, 
      height,
      pY, 
      pU, 
      pV, 
      SrcPitch, 
      DstPitch);

   // YUV2 to YV12
   YUY2toYV12(SrcBuffer, 
      width, 
      height,
      pY, 
      pU, 
      pV, 
      SrcPitch, 
      DstPitch);

   // YVYU to YV12
   YVYUtoYV12(SrcBuffer, 
      width, 
      height,
      pY, 
      pU, 
      pV, 
      SrcPitch, 
      DstPitch);

   delete YV12Buffer;
}


3

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+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;  
					*(pRGBData+(height-i-1)*width*4+j*8+7) = alpha;   
				}  
			}     
		}  
	}  
	else  
	{  
		if (alphaYUV)  
		{  
			for (int i=0; i<height; ++i)  
			{  
				for (int j=0; j<width/2; ++j)  
				{  
					Y1 = *(pYUVData+i*width*3+j*4);  
					U1 = *(pYUVData+i*width*3+j*4+1);  
					Y2 = *(pYUVData+i*width*3+j*4+2);  
					V1 = *(pYUVData+i*width*3+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*3+j*6+2) = R1<0 ? 0 : R1;  
					*(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;  
					*(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;  
					*(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;  
					*(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;  
					*(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;  
				}  
			}  
		}  
		else  
		{  
			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*3+j*6+2) = R1<0 ? 0 : R1;  
					*(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;  
					*(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;  
					*(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;  
					*(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;  
					*(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;  
				}  
			}     
		}  
	}  
	return 0;  
}  


bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight)
{
	if(!pYV12 || !pRGB24)
		return false;

	const long nYLen = long(iHeight * iWidth);
	const int nHfWidth = (iWidth>>1);

	if(nYLen < 1 || nHfWidth < 1) 
		return false;

	unsigned char* yData = pYV12;
	unsigned char* vData = &yData[nYLen];
	unsigned char* uData = &vData[nYLen>>2];
	if(!uData || !vData)
		return false;

	int rgb[3];
	int i, j, m, n, x, y;
	m = -iWidth;
	n = -nHfWidth;
	for(y = 0; y < iHeight; y++)
	{
		m += iWidth;

		if(!(y % 2))
			n += nHfWidth;

		for(x=0; x < iWidth; x++)
		{
			i = m + x;
			j = n + (x>>1);
			rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值
			rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128)  - 0.703125 * (vData[j] - 128)); // g分量值
			rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值
			j = nYLen - iWidth - m + x;
			i = (j<<1) + j;
			for(j=0; j<3; j++)
			{
				if(rgb[j]>=0 && rgb[j]<=255)
					pRGB24[i + j] = rgb[j];
				else
					pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255;
			}
		}
	}

	return true;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值