1、I420->NV21
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;
}
2、NV21->i420
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;
}
3、NV21 ->Bitmap
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;
}
yuv最终将会保存为MP4或者图片
视频:需要使用MediaCodec编码写入视频
图片:课转换后使用YuvImage保存到本地
//保存图片
fun saveImg(data: ByteArray,width: Int,height: Int,imageFilePath:String){
//data为I420,I420->NV21
var l420 = I420ToNV21(data, width, height)
val file = File(imageFilePath)
val yuvimage = YuvImage(l420, ImageFormat.NV21, width, height, null)
val baos = ByteArrayOutputStream()
yuvimage.compressToJpeg(Rect(0, 0, width, height), 100, baos)
val rgbData: ByteArray = baos.toByteArray()
val bmp = BitmapFactory.decodeByteArray(rgbData, 0, rgbData!!.size)
try {
val outStream = FileOutputStream(file)
bmp!!.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
outStream.flush();
outStream.close()
}catch (e:java.lang.Exception){
}
}
在无法确定yuv是否为正确数据 ,情况下可以先保存byte为.yuv文件,使用yuv工具查看
-END