保存I420Frame(NV21 to JPEG)

 public static android.graphics.YuvImage ConvertTo(org.webrtc.VideoRenderer.I420Frame src, int imageFormat) {
        byte[] bytes = new byte[src.yuvStrides[0] * src.height +
                src.yuvStrides[1] * src.height / 2 +
                src.yuvStrides[2] * src.height / 2];
        int[] strides = new int[3];
        switch (imageFormat) {
            default:
                return null;
            case android.graphics.ImageFormat.YV12: {
                ByteBuffer tmp = ByteBuffer.wrap(bytes, 0, src.yuvStrides[0] * src.height);
                copyPlane(src.yuvPlanes[0], tmp);
                tmp = ByteBuffer.wrap(bytes, src.yuvStrides[0] * src.height, src.yuvStrides[2] * src.height / 2);
                copyPlane(src.yuvPlanes[2], tmp);
                tmp = ByteBuffer.wrap(bytes, src.yuvStrides[0] * src.height + src.yuvStrides[2] * src.height / 2, src.yuvStrides[1] * src.height / 2);
                copyPlane(src.yuvPlanes[1], tmp);
                strides[0] = src.yuvStrides[0];
                strides[1] = src.yuvStrides[2];
                strides[2] = src.yuvStrides[1];
                return new YuvImage(bytes, imageFormat, src.width, src.height, strides);
            }

            case android.graphics.ImageFormat.NV21: {
                if (src.yuvStrides[0] != src.width)
                    return null;
                if (src.yuvStrides[1] != src.width / 2)
                    return null;
                if (src.yuvStrides[2] != src.width / 2)
                    return null;

                ByteBuffer tmp = ByteBuffer.wrap(bytes, 0, src.width * src.height);
                copyPlane(src.yuvPlanes[0], tmp);

                byte[] tmparray = new byte[src.width / 2 * src.height / 2];
                tmp = ByteBuffer.wrap(tmparray, 0, src.width / 2 * src.height / 2);

                copyPlane(src.yuvPlanes[2], tmp);
                for (int row = 0; row < src.height / 2; row++) {
                    for (int col = 0; col < src.width / 2; col++) {
                        bytes[src.width * src.height + row * src.width + col * 2] = tmparray[row * src.width / 2 + col];
                    }
                }
                copyPlane(src.yuvPlanes[1], tmp);
                for (int row = 0; row < src.height / 2; row++) {
                    for (int col = 0; col < src.width / 2; col++) {
                        bytes[src.width * src.height + row * src.width + col * 2 + 1] = tmparray[row * src.width / 2 + col];
                    }
                }
                return new YuvImage(bytes, imageFormat, src.width, src.height, null);
            }

        }
    }

调用方法

android.graphics.YuvImage yuvImage = ConvertTo(i420Frame, ImageFormat.NV21);
FileOutputStream fileOutputStream = new FileOutputStream(file);
yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 100, fileOutputStream);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • iPhone的标准推荐是CFNetwork 库编程,其封装好的开源库是 cocoa AsyncSocket库,用它...
    Ethan_Struggle阅读 2,292评论 2 12
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,838评论 0 9
  • # 第一优先级规则声明: # 除了梦境,每一个意识主进程都必须与一个身体参与的机械进程相匹配,否则结束意识主进程。...
    李洞BarryLi阅读 3,941评论 0 1
  • 前言 很久没写过文章了,最近一段时间忙着各种各样的事情,难得寒假有时间便把最近所学的整理及记录下来与大家分享。本篇...
    丶蓝天白云梦阅读 4,226评论 5 45
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,275评论 0 4