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);
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().
User contributions licensed under CC BY-SA 3.0