Converting I420 to BGRA

2

I wang to converting I420 to BGRA ,but i only search the method converting I420 to ARGB:

public static int[] I420toARGB(byte[] yuv, int width, int height)
{

    boolean invertHeight=false;
    if (height<0)
    {
        height=-height;
        invertHeight=true;
    }

    boolean invertWidth=false;
    if (width<0)
    {
        width=-width;
        invertWidth=true;
    }



    int iterations=width*height;

    int[] rgb = new int[iterations];

    for (int i = 0; i<iterations;i++)
    {

        int nearest = (i/width)/2 * (width/2) + (i%width)/2;

        int y = yuv[i] & 0x000000ff;
        int u = yuv[iterations+nearest] & 0x000000ff;


        int v = yuv[iterations + iterations/4 + nearest] & 0x000000ff;


        int b = (int)(y+1.8556*(u-128));

        int g = (int)(y - (0.4681*(v-128) + 0.1872*(u-128)));

        int r = (int)(y+1.5748*(v-128));


        if (b>255){b=255;}
        else if (b<0 ){b = 0;}
        if (g>255){g=255;}
        else if (g<0 ){g = 0;}
        if (r>255){r=255;}
        else if (r<0 ){r = 0;}


        int targetPosition=i;

        if (invertHeight)
        {
            targetPosition=((height-1)-targetPosition/width)*width   +   (targetPosition%width);
        }
        if (invertWidth)
        {
            targetPosition=(targetPosition/width)*width    +    (width-1)-(targetPosition%width);
        }


        rgb[targetPosition] =  (0xff000000) | (0x00ff0000 & r << 16) | (0x0000ff00 & g << 8) | (0x000000ff & b);
    }
    return rgb;

}

so ,if i only modify the last row:

rgb[targetPosition] = (0x000000ff & b) | (0x0000ff00 & g << 8)| (0x00ff0000 & r << 16) | (0xff000000);

android
asked on Stack Overflow Jan 8, 2016 by pengwang

1 Answer

0

No, changing the order of r…g…b…a in the last line is not enough. Also, the original code is wrong, because logical and & takes precedence before shift <<.

bgra[targetPosition] =  255 | (r << 8) | (g << 16) | (b < 24);

But this conversion is painfully slow; I would recommend to use libyuv that uses highly optimized native code. Out of the box, it comes with

int J420ToARGB(const uint8_t* src_y,
               int src_stride_y,
               const uint8_t* src_u,
               int src_stride_u,
               const uint8_t* src_v,
               int src_stride_v,
               uint8_t* dst_argb,
               int dst_stride_argb,
               int width,
               int height);

To convert a single semi-planar byte array, you will need your own wrapper, based on Android420ToARGB().

answered on Stack Overflow Sep 18, 2020 by Alex Cohn

User contributions licensed under CC BY-SA 3.0