YUV格式转RGB格式

最近作Android下图像处理方面的工做,Android下获得的图像其编码格式为YUV,图像处理须要RGB格式,须要进行转换。下面给出遇到的两类YUV格式转换RGB的代码。html


第一种:YUV420SP转RGB
android

遇到的YUV420SP是这种格式:NV21: YYYYYYYY VUVU 函数

void YUV420SP2RGB(char *rgbBuf, char *yuv420sp, int width, int height)
{
    int frameSize = width * height;
    int i = 0, y = 0;
    int uvp = 0, u = 0, v = 0;
    int y1192 = 0, r = 0, g = 0, b = 0;

    for (int j = 0, yp = 0; j < height; j++) 
    {
        uvp = frameSize + (j >> 1) * width;
      	u = 0;
	      v = 0;
	      for (i = 0; i < width; i++, yp++) 
        {
	          y = (0xff & ((int) yuv420sp[yp])) - 16;
	          if (y < 0) y = 0;
	          if ((i & 1) == 0) 
            {
		          v = (0xff & yuv420sp[uvp++]) - 128;
		          u = (0xff & yuv420sp[uvp++]) - 128;
	          }

	          y1192 = 1192 * y;
	          r = (y1192 + 1634 * v);
	          g = (y1192 - 833 * v - 400 * u);
	          b = (y1192 + 2066 * u);

	          if (r < 0) r = 0; else if (r > 262143) r = 262143;
	          if (g < 0) g = 0; else if (g > 262143) g = 262143;
	          if (b < 0) b = 0; else if (b > 262143) b = 262143;

	          rgbBuf[yp * 3] = (byte)(r >> 10);
	          rgbBuf[yp * 3 + 1] = (byte)(g >> 10);
	          rgbBuf[yp * 3 + 2] = (byte)(b >> 10);				
	      }
     }
}

第二种:YUV422转RGB

int convert_yuv_to_rgb_pixel(int y, int u, int v)
{
	unsigned int pixel32 = 0;
	unsigned char *pixel = (unsigned char *)&pixel32;
	int r, g, b;
	r = y + (1.370705 * (v-128));
	g = y - (0.698001 * (v-128)) - (0.337633 * (u-128));
	b = y + (1.732446 * (u-128));
	if(r > 255) r = 255;
	if(g > 255) g = 255;
	if(b > 255) b = 255;
	if(r < 0) r = 0;
	if(g < 0) g = 0;
	if(b < 0) b = 0;
	pixel[0] = r ;
	pixel[1] = g ;
	pixel[2] = b ;
	return pixel32;
}

int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height)
{
	unsigned int in, out = 0;
	unsigned int pixel_16;
	unsigned char pixel_24[3];
	unsigned int pixel32;
	int y0, u, y1, v;

	for(in = 0; in < width * height * 2; in += 4)
	{
		pixel_16 =
			yuv[in + 3] << 24 |
			yuv[in + 2] << 16 |
			yuv[in + 1] <<  8 |
			yuv[in + 0];
		y0 = (pixel_16 & 0x000000ff);
		u  = (pixel_16 & 0x0000ff00) >>  8;
		y1 = (pixel_16 & 0x00ff0000) >> 16;
		v  = (pixel_16 & 0xff000000) >> 24;
		pixel32 = convert_yuv_to_rgb_pixel(y0, u, v);
		pixel_24[0] = (pixel32 & 0x000000ff);
		pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
		pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
		rgb[out++] = pixel_24[0];
		rgb[out++] = pixel_24[1];
		rgb[out++] = pixel_24[2];
		pixel32 = convert_yuv_to_rgb_pixel(y1, u, v);
		pixel_24[0] = (pixel32 & 0x000000ff);
		pixel_24[1] = (pixel32 & 0x0000ff00) >> 8;
		pixel_24[2] = (pixel32 & 0x00ff0000) >> 16;
		rgb[out++] = pixel_24[0];
		rgb[out++] = pixel_24[1];
		rgb[out++] = pixel_24[2];
	}
	return 0;

}

使用时,调用convert_yuv_to_rgb_buffer()这个函数就能够了。关于这个函数的参数解释以下:
yuv:YUV422数据的起始地址编码

rgb:转换后的数据的起始地址spa

width:摄像头采集数据时所设置的图片宽度(如:320).net

height:摄像头采集数据时所设置的图片高度(如:240)code




参考:orm

1.  http://developer.android.com/reference/android/graphics/ImageFormat.htmlhtm

2.  http://www.cnblogs.com/lknlfy/archive/2012/04/09/2439508.htmlblog

3.  http://www.ztyhome.com/android-camera-yuv420/

4.  http://blog.csdn.net/maopig/article/details/7669177

5.  http://blog.csdn.net/perfectpdl/article/details/7616932