YUV格式学习:YUYV、YVYU、UYVY、VYUY格式转换成RGB24

前面文章讲过题目中的YUYV、YVYU、UYVY、VYUY格式,它们都是YUV422的打包格式——即在内存中,Y、U、V都是挨着排序的。它们的名称就表示了Y、U、V的顺序。像YUYV,就是Y、U、Y、V、Y、U、Y、V。在做转换时,就显得很容易、简单了。

因为极其相近,故在将这几种格式全部封闭到一个函数里做。代码如下:

void yuv422packed_to_rgb24(YUV_TYPE type, unsigned char* yuv422p, unsigned char* rgb, int width, int height)
{
    int y, cb, cr;
    int r, g, b;
    int i = 0;
    unsigned char* p;
    unsigned char* p_rgb;

    p = yuv422p;

    p_rgb = rgb;

    init_yuv422p_table();

    for (i = 0; i < width * height / 2; i++)
    {
        switch(type)
        {
        case FMT_YUYV:
            y  = p[0];
            cb = p[1];
            cr = p[3];
            break;
        case FMT_YVYU:
            y  = p[0];
            cr = p[1];
            cb = p[3];
            break;
        case FMT_UYVY:
            cb = p[0];
            y  = p[1];
            cr = p[2];
            break;
        case FMT_VYUY:
            cr = p[0];
            y  = p[1];
            cb = p[2];
            break;
        default:
            break;
        }

        r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000));   //R value
        b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000));   //B value
        g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value

        // 此处可调整RGB排序,BMP图片排序为BGR
        // 默认排序为:RGB
        p_rgb[0] = r;
        p_rgb[1] = g;
        p_rgb[2] = b;

        switch(type)
        {
        case FMT_YUYV:
        case FMT_YVYU:
            y = p[2];
            break;
        case FMT_UYVY:
        case FMT_VYUY:
            y = p[3];
            break;
        default:
            break;
        }

        r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000));   //R value
        b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000));   //B value
        g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value

        p_rgb[3] = r;
        p_rgb[4] = g;
        p_rgb[5] = b;

        p += 4;
        p_rgb += 6;
    }
}

在做转换时,要注意YUV422采样格式,2个Y共用1个U和1个V,因此每一次循环就是读取1个Y、1个U和V转换成R、G、B,再读取下一个Y、U、V。由于UV共用,所以第2次转换时不用再给U、V赋值了。

综上,代码依然十分简单。


2015.8.5 晚上 李迟



发布了483 篇原创文章 · 获赞 254 · 访问量 111万+
展开阅读全文

yuv到rgb视频格式转换

05-23

#define asm __asm typedef unsigned char TUInt8; // [0..255] typedef unsigned long TUInt32; struct TARGB32 // 32 bit color { TUInt8 b,g,r,a; // a is alpha }; struct TPicRegion // 一块颜色数据区的描述,便于参数传递 { TARGB32 * pdata; // 颜色数据首地址 long byte_width; // 一行数据的物理宽度(字节宽度); // abs(byte_width)有可能大于等于width*sizeof(TARGB32); long width; // 像素宽度 long height; // 像素高度 }; // 那么访问一个点的函数可以写为: __forceinline TARGB32 & Pixels( const TPicRegion & pic, const long x, const long y) { return ( (TARGB32 * )((TUInt8 * )pic.pdata + pic.byte_width * y) )[x]; } // 颜色饱和函数 __forceinline long border_color( long color) { if (color > 255 ) return 255 ; else if (color < 0 ) return 0 ; else return color; } __forceinline TARGB32 YUVToRGB32_float( const TUInt8 Y, const TUInt8 U, const TUInt8 V) { TARGB32 result; result.b= border_color( 1.164383 * (Y - 16) + 2.017232*(U - 128) ); result.g= border_color( 1.164383 * (Y - 16) - 0.391762*(U - 128) - 0.812968*(V - 128) ); result.r= border_color( 1.164383 * (Y - 16) + 1.596027*(V - 128) ); result.a = 255 ; return result; } void DECODE_YUYV_Float( const TUInt8 * pYUYV, const TPicRegion & DstPic) { assert((DstPic.width & 1 ) == 0 ); TARGB32 * pDstLine = DstPic.pdata; for ( long y = 0 ;y < DstPic.height; ++ y) { for ( long x = 0 ;x < DstPic.width;x += 2 ) { pDstLine[x + 0 ] = YUVToRGB32_float(pYUYV[ 0 ],pYUYV[ 1 ],pYUYV[ 3 ]); pDstLine[x + 1 ] = YUVToRGB32_float(pYUYV[ 2 ],pYUYV[ 1 ],pYUYV[ 3 ]); pYUYV += 4 ; } ((TUInt8 *& )pDstLine) += DstPic.byte_width; } } 哪位大神帮忙写个 main()函数 让我看看具体输出是啥样的 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览