Android系统中Y'UV420p (NV21)到ARGB8888的转换

来源:互联网 发布:tcpip协议 默认端口号 编辑:程序博客网 时间:2024/06/03 09:01

http://en.wikipedia.org/wiki/YUV

This format (NV21) is the standard picture format on android camera preview. YUV 4:2:0 planar image, with 8 bit Y samples, followed by interleaved V/U plane with 8bit 2x2 subsampled chroma samples.[8]

Java source code used on Android:

但是NV21在Microsoft中的定义是:

Microsoft defines this format as follows:

 "The same as NV12, except that Cb and Cr samples are swapped so that the chroma array of unsigned char would have Cr followed by Cb for each sample (such that if addressed as a little-endian WORD type, Cr would be in the LSBs and Cb would be in the MSBs)."

参考: http://www.fourcc.org/yuv.php

/** * Converts YUV420 NV21 to ARGB8888 *  * @param data byte array on YUV420 NV21 format. * @param width pixels width * @param height pixels height * @return a ARGB8888 pixels int array. Where each int is a pixels ARGB.  */public static int[] convertYUV420_NV21toARGB8888(byte [] data, int width, int height) {    int size = width*height;    int offset = size;    int[] pixels = new int[size];    int u, v, y1, y2, y3, y4;     // i along Y and the final pixels    // k along pixels U and V    for(int i=0, k=0; i < size; i+=2, k+=2) {        y1 = data[i  ]&0xff;        y2 = data[i+1]&0xff;        y3 = data[width+i  ]&0xff;        y4 = data[width+i+1]&0xff;         u = data[offset+k  ]&0xff;        v = data[offset+k+1]&0xff;        u = u-128;        v = v-128;         pixels[i  ] = convertYUVtoARGB(y1, u, v);        pixels[i+1] = convertYUVtoARGB(y2, u, v);        pixels[width+i  ] = convertYUVtoARGB(y3, u, v);        pixels[width+i+1] = convertYUVtoARGB(y4, u, v);         if (i!=0 && (i+2)%width==0)            i+=width;    }     return pixels;} private static int convertYUVtoARGB(int y, int u, int v) {    int r,g,b;     r = y + (int)1.402f*u;    g = y - (int)(0.344f*v +0.714f*u);    b = y + (int)1.772f*v;    r = r>255? 255 : r<0 ? 0 : r;    g = g>255? 255 : g<0 ? 0 : g;    b = b>255? 255 : b<0 ? 0 : b;    return 0xff000000 | (r<<16) | (g<<8) | b;}


 

 

http://stackoverflow.com/questions/16737749/onpreviewframe-yuv-grayscale-skewed

http://stackoverflow.com/questions/8340128/decoding-yuv-to-rgb-in-c-c-with-ndk

http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/microsoft.devices.photocamera.ycbcrpixellayout(v=vs.105).aspx

 

在Android API Level-9中YUV格式采用YV12(YVU420)格式,而且若Y分量的宽度不是16的整倍数时,进行扩展。但是Y分量的高是奇数时,U,V分量的高是hight/2

http://stackoverflow.com/questions/16737749/onpreviewframe-yuv-grayscale-skewed

public static final int YV12

Added in API level 9 Android YUV format.

This format is exposed to software decoders and applications.

YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed by (W/2) x (H/2) Cr and Cb planes.

This format assumes

an even width an even height a horizontal stride multiple of 16 pixels a vertical stride equal to the height y_size = stride * height c_stride = ALIGN(stride/2, 16) c_size = c_stride * height/2 size = y_size + c_size * 2 cr_offset = y_size cb_offset = y_size + c_size

 

原创粉丝点击