0
点赞
收藏
分享

微信扫一扫

简单YUV数据转换二


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


举报

相关推荐

0 条评论