• 简单YUV数据转换二


    1、I420->NV21 

    1. public static byte[] I420ToNV21(byte[] input, int width, int height) {
    2. byte[] output = new byte[4147200];
    3. int frameSize = width * height;
    4. int qFrameSize = frameSize / 4;
    5. int tempFrameSize = frameSize * 5 / 4;
    6. System.arraycopy(input, 0, output, 0, frameSize);
    7. for(int i = 0; i < qFrameSize; ++i) {
    8. output[frameSize + i * 2] = input[tempFrameSize + i];
    9. output[frameSize + i * 2 + 1] = input[frameSize + i];
    10. }
    11. return output;
    12. }

     2、NV21->i420

    1. public byte[] nv21ToI420(byte[] data, int width, int height) {
    2. byte[] ret = globalBuffer;
    3. int total = width * height;
    4. ByteBuffer bufferY = ByteBuffer.wrap(ret, 0, total);
    5. ByteBuffer bufferU = ByteBuffer.wrap(ret, total, total / 4);
    6. ByteBuffer bufferV = ByteBuffer.wrap(ret, total + total / 4, total / 4);
    7. bufferY.put(data, 0, total);
    8. for (int i=total; i2) {
    9. bufferV.put(data[i]);
    10. bufferU.put(data[i+1]);
    11. }
    12. return ret;
    13. }

    3、NV21 ->Bitmap

    1. public static Bitmap NV21ToBitmap(Context context, byte[] nv21, int width, int height) {
    2. RenderScript rs = RenderScript.create(context);
    3. ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
    4. Builder yuvType = null;
    5. yuvType = (new Builder(rs, Element.U8(rs))).setX(nv21.length);
    6. Allocation in = Allocation.createTyped(rs, yuvType.create(), 1);
    7. Builder rgbaType = (new Builder(rs, Element.RGBA_8888(rs))).setX(width).setY(height);
    8. Allocation out = Allocation.createTyped(rs, rgbaType.create(), 1);
    9. in.copyFrom(nv21);
    10. yuvToRgbIntrinsic.setInput(in);
    11. yuvToRgbIntrinsic.forEach(out);
    12. Bitmap bmpout = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    13. out.copyTo(bmpout);
    14. return bmpout;
    15. }

    yuv最终将会保存为MP4或者图片

    视频:需要使用MediaCodec编码写入视频

    图片:课转换后使用YuvImage保存到本地

    1. //保存图片
    2. fun saveImg(data: ByteArray,width: Int,height: Int,imageFilePath:String){
    3. //data为I420,I420->NV21
    4. var l420 = I420ToNV21(data, width, height)
    5. val file = File(imageFilePath)
    6. val yuvimage = YuvImage(l420, ImageFormat.NV21, width, height, null)
    7. val baos = ByteArrayOutputStream()
    8. yuvimage.compressToJpeg(Rect(0, 0, width, height), 100, baos)
    9. val rgbData: ByteArray = baos.toByteArray()
    10. val bmp = BitmapFactory.decodeByteArray(rgbData, 0, rgbData!!.size)
    11. try {
    12. val outStream = FileOutputStream(file)
    13. bmp!!.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
    14. outStream.flush();
    15. outStream.close()
    16. }catch (e:java.lang.Exception){
    17. }
    18. }

              在无法确定yuv是否为正确数据 ,情况下可以先保存byte为.yuv文件,使用yuv工具查看                   YUV工具下载,无需积分

          -END

  • 相关阅读:
    JavaScript 数组操作
    alertmanager集群莫名发送resolve消息的问题探究
    【面试题】 javaScript 进阶之路 --- 《加深理解回调函数》
    altera系列fifo和ram
    C++11实现日期和时间相关编程
    自定义View之Measure(二)
    基于工业智能网关的PLC远程控制解决方案
    8086 汇编笔记(八):转移指令的原理
    CompletableFuture原理与实践-外卖商家端API的异步化
    pandas Excelwriter, writer.save() 输出xlsx导致文件只读的问题
  • 原文地址:https://blog.csdn.net/generallizhong/article/details/132813714