雷霄骅《最简单的视音频播放示例2:GDI播放YUV, RGB 》中YUV转RGB的过程

1 篇文章 0 订阅
1 篇文章 0 订阅

雷霄骅在 https://blog.csdn.net/leixiaohua1020/article/details/40266503 一文中提到了yuv转rgb的代码,通过简单的改造,就可以直观的看出yuv的模样。

测试rgb的渲染。

改动CONVERT_YUV420PtoRGB24 的代码如下。

void CONVERT_YUV420PtoRGB24(unsigned char* yuv_src, unsigned char* rgb_dst, int nWidth, int nHeight)
{
    unsigned char Y, U, V, R, G, B;
    unsigned char* y_planar, * u_planar, * v_planar;
    int offSet = 0;
    int rgb_width = nWidth * 3;
    int ypSize = nWidth * nHeight;
    int upSize = (ypSize >> 2); 
    y_planar = yuv_src;
    u_planar = yuv_src + ypSize;
    v_planar = u_planar + upSize;
    for (int i = 0; i < nHeight; i++)
    {
        for (int j = 0; j < nWidth; j++)
        {
            R = 255;
            G = 0;
            B = 0;

            offSet = rgb_width * i + j * 3;
            rgb_dst[offSet] = B;
            rgb_dst[offSet + 1] = G;
            rgb_dst[offSet + 2] = R;
        }
    }
}

期待的结果为整个窗口为红色。

只渲染yuv中的y数据。

改动CONVERT_YUV420PtoRGB24 的代码如下。

void CONVERT_YUV420PtoRGB24(unsigned char* yuv_src, unsigned char* rgb_dst, int nWidth, int nHeight)
{
    unsigned char Y, U, V, R, G, B;
    unsigned char* y_planar, * u_planar, * v_planar;
    int offSet = 0;
    int rgb_width = nWidth * 3;
    int ypSize = nWidth * nHeight;
    int upSize = (ypSize >> 2);
    y_planar = yuv_src;
    u_planar = yuv_src + ypSize;
    v_planar = u_planar + upSize;
    for (int i = 0; i < nHeight; i++)
    {
        for (int j = 0; j < nWidth; j++)
        {
            Y = *(y_planar + nWidth * i + j);
            R = Y;
            G = Y;
            B = Y;
            offSet = rgb_width * i + j * 3;
            rgb_dst[offSet] = B;
            rgb_dst[offSet + 1] = G;
            rgb_dst[offSet + 2] = R;
        }
    }
}

运行后的结果为:

在这里插入图片描述
可以看出,Y代表的就是亮度信息。

添加uv数据

改动CONVERT_YUV420PtoRGB24 的代码如下。值得注意的是,雷兄给的第一种方法,颜色有些许偏差,查资料可以看出来,第二种方法更加主流。https://stackoverflow.com/questions/1737726/how-to-perform-rgb-yuv-conversion-in-c-c

void CONVERT_YUV420PtoRGB24(unsigned char* yuv_src, unsigned char* rgb_dst, int nWidth, int nHeight)
{
    unsigned char Y, U, V, R, G, B;
    unsigned char* y_planar, * u_planar, * v_planar;
    int offSet = 0;
    int rgb_width = nWidth * 3;
    int ypSize = nWidth * nHeight;
    int upSize = (ypSize >> 2);
    int u_width = (nWidth >> 1);
    y_planar = yuv_src;
    u_planar = yuv_src + ypSize;
    v_planar = u_planar + upSize;
    for (int i = 0; i < nHeight; i++)
    {
        for (int j = 0; j < nWidth; j++)
        {
            Y = *(y_planar + nWidth * i + j);
            offSet = (i >> 1) * (u_width)+(j >> 1);
            U = *(v_planar + offSet);
            V = *(u_planar + offSet);
            int C, D, E;
            C = Y - 16;
            D = U - 128;
            E = V - 128;
            R = CONVERT_ADJUST((298 * C + 409 * E + 128) >> 8);
            G = CONVERT_ADJUST((298 * C - 100 * D - 208 * E + 128) >> 8);
            B = CONVERT_ADJUST((298 * C + 516 * D + 128) >> 8);
            offSet = rgb_width * i + j * 3;
            rgb_dst[offSet] = B; // 如果不想再调用CHANGE_ENDIAN_PIC,可以直接调换 b和r的赋值位置。
            rgb_dst[offSet + 1] = G;
            rgb_dst[offSet + 2] = R;
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值