Android 视频 YUV i420格式转换为位图Bitmap
YUV(YCbCr,图像除了RGB,还有YUV)
定义:是电视系统所采用的一种颜色编码方法
- Y 标识明亮度,也就是灰阶值
- U和V标识的色度,描述影像色彩和饱和度
YUV常见格式:
YUV 4:2:0
YUV 4:2:2
YUV 4:4:4
YUV存储格式
YUV格式有两大类:planar和packed。
对于planar的YUV格式,先连续存储所有像素点的Y,随后存储U、V。存储类型表示为采样方式后缀加P。
对于packed的YUV格式,每个像素点的Y,U,V是连续交错存储的。存储类型表示为采样方式后缀加SP
YUV i420格式转换为位图Bitmap
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type.Builder;
public static byte[] I420ToNV21(byte[] input, int width, int height) {
byte[] output = new byte[4147200];
int frameSize = width * height;
int qFrameSize = frameSize / 4;
int tempFrameSize = frameSize * 5 / 4;
System.arraycopy(input, 0, output, 0, frameSize);
for(int i = 0; i < qFrameSize; ++i) {
output[frameSize + i * 2] = input[tempFrameSize + i];
output[frameSize + i * 2 + 1] = input[frameSize + i];
}
return output;
}
public byte[] nv21ToI420(byte[] data, int width, int height) {
byte[] ret = globalBuffer;
int total = width * height;
ByteBuffer bufferY = ByteBuffer.wrap(ret, 0, total);
ByteBuffer bufferU = ByteBuffer.wrap(ret, total, total / 4);
ByteBuffer bufferV = ByteBuffer.wrap(ret, total + total / 4, total / 4);
bufferY.put(data, 0, total);
for (int i=total; i<data.length; i+=2) {
bufferV.put(data[i]);
bufferU.put(data[i+1]);
}
return ret;
}
public static Bitmap NV21ToBitmap(Context context, byte[] nv21, int width, int height) {
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Builder yuvType = null;
yuvType = (new Builder(rs, Element.U8(rs))).setX(nv21.length);
Allocation in = Allocation.createTyped(rs, yuvType.create(), 1);
Builder rgbaType = (new Builder(rs, Element.RGBA_8888(rs))).setX(width).setY(height);
Allocation out = Allocation.createTyped(rs, rgbaType.create(), 1);
in.copyFrom(nv21);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
Bitmap bmpout = Bitmap.createBitmap(width, height, Config.ARGB_8888);
out.copyTo(bmpout);
return bmpout;
}
参考:
- http://www.zeroplace.cn/article.asp?id=984
- YUV数据格式
- Android——Nv21高效率转Bitmap