C语言实现RGB packet格式转YUV(NV21)格式

Posted 代二毛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言实现RGB packet格式转YUV(NV21)格式相关的知识,希望对你有一定的参考价值。

前言:

此函数用于RGB packet(R G B R G B······)格式转YUV的NV21格式,保存NV21图像的内存由外部申请并传入。函数的具体实现原理在这里不做介绍,对RGB格式和YUV格式不熟悉的请自行查阅资料,该函数可直接拷贝过去使用。

代码:

/*
* 输入:data--RGB的数据
* 	w--RGB图像的宽
* 	h--RGB图像的高
* 输出:yuv--转换得到的yuv数据
*/
void RgbToNv12(Uint8* data, Uint32 w, Uint32 h, Uint8* yuv)
{
    Uint32 row_bytes;
    Uint8* uv;
    Uint8* y;
    Uint8 r, g, b;
    Uint8 y_val, u_val, v_val;
   
    Uint8 * img;
    Uint32 i, j;
    y = yuv;
    uv = yuv + w * h;

    row_bytes = (w * 3 );  
    h = h & ~1;
    //先转换Y
    for (i = 0; i < h; i++)
    {   
        img = data + row_bytes * i;
        for (j = 0; j <w; j++)
        {
            r = *(img+3*j);
            g = *(img+3*j+1);
            b = *(img+3*j+2);
            if(r>=254&&g>=254&&b>=254)
            {
    	        y_val=254;
    	        *y++ = y_val;
   	        continue;
            }
           y_val = (Uint8)(((int32)(299 * r) + (int32)(597 * g) + (int32)(114 * b)) / 1000);
           *y++ = y_val;
        }
    }
    //转换uv  
    for (i = 0; i <h; i += 2)
    {
	img = data + row_bytes*(h-i-1);
 	for (j = 0; j < w; j+=2)
  	{
	    r = *(img+3*j);
	    g = *(img+3*j+1);
	    b = *(img+3*j+2);
	    u_val= (Uint8)(((int32)(-168.7 * r) - (int32)(331.3 * g) + (int32)(500 * b) + 128000) / 1000);
	    v_val= (Uint8)(((int32)(500 * r) - (int32)(418.7 * g) - (int32)(81.3 * b) + 128000) / 1000);
	    *uv++ = v_val;
	    *uv++ = u_val;
	}
   }
}	         

以上是关于C语言实现RGB packet格式转YUV(NV21)格式的主要内容,如果未能解决你的问题,请参考以下文章

如何将rgb 模式转换成 yuv 模式

c语言如何实现将一张RGB的图片转化为YUV

C语言怎么截屏并将数据转换成RGB或YUV420

如何把摄像头采集的rgb图像转成yuv格式,并进行H264硬编码?

图像RGB2YUV与YUV2RGB格式互转介绍

YUV 转 RGB 和 CreateBitmap ......格式是啥?