安卓NV21与argb8888,arg565,jpeg之间的转换。使用libyuv和turbojpeg加速编解码

项目需求:把摄像头出来的NV21的YUV数据,转换为JPEG传导电脑端显示。NV21数据比较大,直接用于传输会比较耗费网络资源,所以需要压缩为jpg图片数据传输。之前考虑编码为H264传输,到电脑端在解码显示。经过测试,效果也不是很理想。由于应用场景只是在内网,传输效率还是比较高的。

1.安卓有现成的YUVimage可以压缩为 

YuvImage yuvImage = new YuvImage(yuv, ImageFormat.NV21,w,h,null);
ByteArrayOutputStream jpeg = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0,0,w,h),100,jpeg);

这个方法底层是使用jpeg库进行压缩的,有内存泄露(之前做项目的时候,压力测试扛不住半天就莫名崩溃,当时找这个BUG找了大概一周的时间,几乎每个可能出现内存泄露的地方都一一做了排查,根本想不到是系统底层的问题。后来无意间在论坛上发现了YUVimage压缩jpeg数据有内存泄露的BUG才去查了一下底层实现,果然如此。),经过多次调用后,会出现内存溢出,程序崩溃。居然系统自带的方法不能游泳,无奈,只能去寻找其他的解决方法。找了JPEG压缩算法,另外发现的turbojpeg加速压缩算法。

 

2.另外由于NV21不能直接作为JPEG压缩算法的输入,需要转换为I420。刚开始直接使用java转换NV21为I420,发现效率较低。固使用libyuv神库解决这样的转换问题。

3.经过整理:完善了相关的转换。目前实现了NV21到argb,jpeg等的相关转换

(1)nv21转换为JPEG

  1. public static native int yuv2jpeg(byte[] nv21,int w,int h,int subsample,byte[] jpeg ,int quality,int flags);
    
    (2)yuv裁剪,然后压缩为jpeg
    
    public static native int yuvCrop2jpeg(byte[] nv21,int w,int h,int subsample,int x,int y,int cropW,int cropH,byte[] jpeg ,int quality,int flags);
    
    (3)获取jpeg图片的相关消息
    public static native int getjpegInfo(byte[] jpeg,int size,int[] info);
    
    (4)jpeg转换为NV21
    public static native int jpeg2yuv(byte[] jpeg,int size,byte[] yuv,int w,int h);
    
    (5)jpeg图片转换为argb8888
    public static native int jpeg2argb(byte[] jpeg,int size,byte[] argb,int w,int h);
    
    (6)yuv数据转换为argb8888
    public static native int yuv2argb(byte[] yuv,int size,int[] argb,int w,int h);
    
    (7)NV21转换为rgb565
    public static native int yuv2rgb565(byte[] yuv,int size,byte[] rgb565,int w,int h);

代码实现和相关Demo见github:

https://github.com/liushiyun8/YuvJpegDemo

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值