Android 视频 YUV i420格式转换为位图Bitmap

7 篇文章 0 订阅
4 篇文章 0 订阅

Android 视频 YUV i420格式转换为位图Bitmap

YUV基础描述


YUV(YCbCr,图像除了RGB,还有YUV)

定义:是电视系统所采用的一种颜色编码方法

  • Y 标识明亮度,也就是灰阶值
  • U和V标识的色度,描述影像色彩和饱和度

YUV常见格式:

YUV 4:2:0
YUV 4:2:2
YUV 4:4:4


YUV存储格式

YUV格式有两大类:planar和packed。

对于planar的YUV格式,先连续存储所有像素点的Y,随后存储U、V。存储类型表示为采样方式后缀加P。

对于packed的YUV格式,每个像素点的Y,U,V是连续交错存储的。存储类型表示为采样方式后缀加SP


YUV i420格式转换为位图Bitmap

import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type.Builder;

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;
}

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;
}

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;
}

参考:

  1. http://www.zeroplace.cn/article.asp?id=984
  2. YUV数据格式
  3. Android——Nv21高效率转Bitmap
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初心一点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值