美文网首页
YUY2(YUV) 与 RGB 格式图片的相互转换

YUY2(YUV) 与 RGB 格式图片的相互转换

作者: 技术笔记 | 来源:发表于2019-10-31 14:36 被阅读0次

    [版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    本文链接:https://blog.csdn.net/jtujtujtu/article/details/3874621]

    YUY2经常用于电视制式以及许多摄像头的输出格式.而我们在处理时经常需要将其转化为RGB进行处理,这里简单介绍下YUY2(YUV)与RGB之间相互转化的关系:

    http://msdn2.microsoft.com/en-us/lib

    YUY2(YUV) To RGB:

    C = Y - 16
    D = U - 128
    E = V - 128

    R = clip(( 298 * C           + 409 * E + 128) >> 8)
    G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
    B = clip(( 298 * C + 516 * D           + 128) >> 8)
    

    其中 clip()为限制函数,将其取值限制在0-255之间.

    RGB To YUY2(YUV):

    Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16
    U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128
    V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128
    

    上述两个公式在代码中的:

    int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB);
    int RGB2YUV(void* pRGB, void* pYUVX, int width, int height, bool alphaYUV, bool alphaRGB);
    

    函数中转换。

    在诸如摄像头的数据获取中,我们往往需要直接在YUY2(YUV)空间上进行一些图象处理,我们希望能够在YUY2
    (YUV)进行一些RGB上可以做到的处理。这里已blending为例,将两张带有透明度的YUY2(YUV)图片进行叠加,
    以达到在RGB空间进行图像合成的效果。

    RGB空间进行图像叠加,通常背景(BG)是不透明的,而前景(FG)是带有透明度的。在RGB空间,可以简单表示为:

    Rdest = Rfg*alpha + Rbg*(1-alpha);
    Gdest = Gfg*alpha + Gbg*(1-alpha);
    Bdest = Bfg*alpha + Bbg*(1-alpha);
    

    Rdest、Gdest、Bdest 为最终合成后的像素值

    考虑到

    Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16
    U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128
    V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128
    

    我们可以推导出

    (Ydest-16)<<8 = ((Yfg-16)<<8)*alpha + ((Ybg-16)<<8)*(1-alpha);
    (Udest-128)<<8 = ((Ufg-128)<<8)*alpha + ((Ubg-128)<<8)*(1-alpha);
    (Vdest-128)<<8 = ((Vfg-128)<<8)*alpha + ((Vbg-128)<<8)*(1-alpha);
    

    从而可以得到

    Ydest = (Yfg-16)*alpha + (Ybg-16)*(1-alpha) + 16;
    Udest = (Ufg-128)*alpha + (Ubg-128)*(1-alpha) + 128;
    Vdest = (Vfg-128)*alpha + (Vbg-128)*(1-alpha) + 128;
    

    这个叠加过程在函数

    int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
    

    中实现。

    由于本文针对摄像头采集所得的数据进行处理,因此数据为YUY2格式,即4个字节来表示两个像素点的YUV信息,
    排列为Y1 U1 Y2 V2, 对于像素点1为(Y1, U1, V1),像素点2为(Y2, U1, V1)。即两个像素点共用U、V信息。

    这里假设带有alpha透明度的YUV格式用6个字节来表示两个像素点的YUV以及alpha信息,排列为 Y1 U1 Y2 V1 alpha1 alpha2
    其中像素点1为(Y1, U1, V1, alpha1),像素点2为(Y2, U1, V1, alpha2)。其中alpha为对应点的透明度信息。

    而带有alpha透明度RGB格式的图片,假设为32bits的BMP图片,每个像素点用4bytes来表示,分别为B G R alpha信息。

    上述函数的具体实现为:

    //////////////////////////////////////////////////////////////////////////
    // YUV2RGB
    // pYUV         point to the YUV data
    // pRGB         point to the RGB data
    // width        width of the picture
    // height       height of the picture
    // alphaYUV     is there an alpha channel in YUV
    // alphaRGB     is there an alpha channel in RGB
    //////////////////////////////////////////////////////////////////////////
    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;
    }
    
    //////////////////////////////////////////////////////////////////////////
    // RGB2YUV
    // pRGB         point to the RGB data
    // pYUV         point to the YUV data
    // width        width of the picture
    // height       height of the picture
    // alphaYUV     is there an alpha channel in YUV
    // alphaRGB     is there an alpha channel in RGB
    //////////////////////////////////////////////////////////////////////////
    int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB)
    {
        if (NULL == pRGB)
        {
            return -1;
        }
        unsigned char* pRGBData = (unsigned char *)pRGB;
        unsigned char* pYUVData = (unsigned char *)pYUV;
        if (NULL == pYUVData)
        {
            if (alphaYUV)
            {
                pYUVData = new unsigned char[width*height*3];
            }
            else
                pYUVData = new unsigned char[width*height*2];
        }
        int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1;
        int alpha1, alpha2;
        if (alphaYUV)
        {
            if (alphaRGB)
            {
                for (int i=0; i<height; ++i)
                {
                    for (int j=0; j<width/2; ++j)
                    {
                        B1 = *(pRGBData+(height-i-1)*width*4+j*8);
                        G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
                        R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
                        alpha1 = *(pRGBData+(height-i-1)*width*4+j*8+3);
                        B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
                        G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
                        R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
                        alpha2 = *(pRGBData+(height-i-1)*width*4+j*8+7);
                        Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
                        U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
                        Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
                        V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
                        *(pYUVData+i*width*3+j*6) = Y1;
                        *(pYUVData+i*width*3+j*6+1) = U1;
                        *(pYUVData+i*width*3+j*6+2) = Y2;
                        *(pYUVData+i*width*3+j*6+3) = V1;
                        *(pYUVData+i*width*3+j*6+4) = alpha1;
                        *(pYUVData+i*width*3+j*6+5) = alpha2;
                    }
                }   
            }
            else
            {
                unsigned char alpha = 255;
                for (int i=0; i<height; ++i)
                {
                    for (int j=0; j<width/2; ++j)
                    {
                        B1 = *(pRGBData+(height-i-1)*width*3+j*6);
                        G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
                        R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
                        B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
                        G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
                        R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
                        Y1 = ((66*R1+129*G1+25*B1+128)>>8) + 16;
                        U1 = ((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2 + 128;
                        Y2 = ((66*R2+129*G2+25*B2+128)>>8) + 16;
                        V1 = ((112*R1-94*G1-18*B1+128)>>8 + (112*R2-94*G2-18*B2+128)>>8)/2 + 128;
                        Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
                        U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
                        Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
                        V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
                        *(pYUVData+i*width*3+j*6) = Y1;
                        *(pYUVData+i*width*3+j*6+1) = U1;
                        *(pYUVData+i*width*3+j*6+2) = Y2;
                        *(pYUVData+i*width*3+j*6+3) = V1;
                        *(pYUVData+i*width*3+j*6+4) = alpha;
                        *(pYUVData+i*width*3+j*6+5) = alpha;
                    }
                }   
            }
        }
        else
        {
            if (alphaRGB)
            {
                for (int i=0; i<height; ++i)
                {
                    for (int j=0; j<width/2; ++j)
                    {
                        B1 = *(pRGBData+(height-i-1)*width*4+j*8);
                        G1 = *(pRGBData+(height-i-1)*width*4+j*8+1);
                        R1 = *(pRGBData+(height-i-1)*width*4+j*8+2);
                        B2 = *(pRGBData+(height-i-1)*width*4+j*8+4);
                        G2 = *(pRGBData+(height-i-1)*width*4+j*8+5);
                        R2 = *(pRGBData+(height-i-1)*width*4+j*8+6);
                        Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
                        U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
                        Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
                        V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
                        *(pYUVData+i*width*2+j*4) = Y1;
                        *(pYUVData+i*width*2+j*4+1) = U1;
                        *(pYUVData+i*width*2+j*4+2) = Y2;
                        *(pYUVData+i*width*2+j*4+3) = V1;
                    }
                }   
            }
            else
            {
                for (int i=0; i<height; ++i)
                {
                    for (int j=0; j<width/2; ++j)
                    {
                        B1 = *(pRGBData+(height-i-1)*width*3+j*6);
                        G1 = *(pRGBData+(height-i-1)*width*3+j*6+1);
                        R1 = *(pRGBData+(height-i-1)*width*3+j*6+2);
                        B2 = *(pRGBData+(height-i-1)*width*3+j*6+3);
                        G2 = *(pRGBData+(height-i-1)*width*3+j*6+4);
                        R2 = *(pRGBData+(height-i-1)*width*3+j*6+5);
                        Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
                        U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
                        Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
                        V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
                        *(pYUVData+i*width*2+j*4) = Y1;
                        *(pYUVData+i*width*2+j*4+1) = U1;
                        *(pYUVData+i*width*2+j*4+2) = Y2;
                        *(pYUVData+i*width*2+j*4+3) = V1;
                    }
                }   
            }
        }
        return 0;
    }
    
    //////////////////////////////////////////////////////////////////////////
    // pGBYUV           point to the background YUV data
    // pFGYUV           point to the foreground YUV data
    // width            width of the picture
    // height           height of the picture
    // alphaBG          is there an alpha channel in background YUV data
    // alphaFG          is there an alpha channel in fourground YUV data
    //////////////////////////////////////////////////////////////////////////
    int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
    {
        if (NULL == pBGYUV || NULL == pFGYUV)
        {
            return -1;
        }
        unsigned char* pBGData = (unsigned char*)pBGYUV;
        unsigned char* pFGData = (unsigned char*)pFGYUV;
        if (!alphaFG)
        {
            if (!alphaBG)
            {
                memcpy(pBGData, pFGData, width*height*2);
            }
            else
            {
                for (int i=0; i<height; ++i)
                {
                    for (int j=0; j<width/2; ++j)
                    {
                        *(pBGData+i*width*2+j*4) = *(pFGData+i*width*2+j*4);
                        *(pBGData+i*width*2+j*4+1) = *(pFGData+i*width*2+j*4+1);
                        *(pBGData+i*width*2+j*4+2) = *(pFGData+i*width*2+j*4+2);
                        *(pBGData+i*width*2+j*4+3) = *(pFGData+i*width*2+j*4+3);
                    }
                }
            }
        }
        int Y11, U11, V11, Y12, Y21, U21, V21, Y22;
        int alpha1, alpha2;
        if (!alphaBG)
        {
            for (int i=0; i<height; ++i)
            {
                for (int j=0; j<width/2; ++j)
                {
                    Y11 = *(pBGData+i*width*2+j*4);
                    U11 = *(pBGData+i*width*2+j*4+1);
                    Y12 = *(pBGData+i*width*2+j*4+2);
                    V11 = *(pBGData+i*width*2+j*4+3);
    
                    Y21 = *(pFGData+i*width*3+j*6);
                    U21 = *(pFGData+i*width*3+j*6+1);
                    Y22 = *(pFGData+i*width*3+j*6+2);
                    V21 = *(pFGData+i*width*3+j*6+3);
                    alpha1 = *(pFGData+i*width*3+j*6+4);
                    alpha2 = *(pFGData+i*width*3+j*6+5);
    
                    *(pBGData+i*width*2+j*4) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
                    *(pBGData+i*width*2+j*4+1) = ((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255 + (U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
                    *(pBGData+i*width*2+j*4+3) = ((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255 + (V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
                    *(pBGData+i*width*2+j*4+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
                }
            }
        }
        else
        {
            for (int i=0; i<height; ++i)
            {
                for (int j=0; j<width/2; ++j)
                {
                    Y11 = *(pBGData+i*width*3+j*6);
                    U11 = *(pBGData+i*width*3+j*6+1);
                    Y12 = *(pBGData+i*width*3+j*6+2);
                    V11 = *(pBGData+i*width*3+j*6+3);
    
                    Y21 = *(pFGData+i*width*3+j*6);
                    U21 = *(pFGData+i*width*3+j*6+1);
                    Y22 = *(pFGData+i*width*3+j*6+2);
                    V21 = *(pFGData+i*width*3+j*6+3);
                    alpha1 = *(pFGData+i*width*3+j*6+4);
                    alpha2 = *(pFGData+i*width*3+j*6+5);
    
                    *(pBGData+i*width*3+j*6) = (Y21-16)*alpha1/255+(Y11-16)*(255-alpha1)/255+16;
                    *(pBGData+i*width*3+j*6+1) = ((U21-128)*alpha1/255+(U11-128)*(255-alpha1)/255 + (U21-128)*alpha2/255+(U11-128)*(255-alpha2)/255)/2+128;
                    *(pBGData+i*width*3+j*6+3) = ((V21-128)*alpha1/255+(V11-128)*(255-alpha1)/255 + (V21-128)*alpha2/255+(V11-128)*(255-alpha2)/255)/2+128;
                    *(pBGData+i*width*3+j*6+2) = (Y22-16)*alpha2/255+(Y12-16)*(255-alpha2)/255+16;
                }
            }
        }
        return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:YUY2(YUV) 与 RGB 格式图片的相互转换

          本文链接:https://www.haomeiwen.com/subject/wyhtbctx.html