Android Camera2 ImageReader YUV420_888快速转bitmap argb888的方式

从 Android 12 开始,RenderScript API 已被弃用。Google推荐使用更加高效的Vulkan。这篇文件还是介绍RenderScript 的使用,RenderScript 相对比较简单一些。

RenderScript 是用于在 Android 上以高性能运行计算密集型任务的框架。RenderScript 专为数据并行计算而设计,不过串行工作负载也可以从中受益。RenderScript 运行时可以并行安排设备上可用的多个处理器(如多核 CPU 和 GPU)上的工作负载,使开发者能够专注于表达算法而不是调度工作。RenderScript 对于专注于图像处理、计算摄影或计算机视觉的应用来说尤其有用。

关于RenderScript ,Google的官方介绍文档。

https://source.android.google.cn/docs/core/architecture/vndk/renderscript?hl=zh-cn

RenderScript 使用示例:

下面示例内容是,在imageReader的回调里面,实时的将yuv420_888转为bitmap。

mYuvImageReader = ImageReader.newInstance(1920, 1080,
                    ImageFormat.YUV_420_888, 4);

private final ImageReader.OnImageAvailableListener mOnYuvImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {

        @Override
        public void onImageAvailable(ImageReader reader) {
            Image image = reader.acquireLatestImage();

            if (image != null) {
                Log.e(TAG,"YUV_420_888_toRGBIntrinsics start");
                mBitMap = YUV_420_888_toRGBIntrinsics(image,getActivity());
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                       showImage(mBitMap);
                    }
                });
                Log.e(TAG,"YUV_420_888_toRGBIntrinsics end");
            }
        }
    };
 private static RenderScript rs;
    private static Bitmap YUV_420_888_toRGBIntrinsics(Image image,Context context) {

        if (image == null) return null;

        int W = image.getWidth();
        int H = image.getHeight();

        Image.Plane Y = image.getPlanes()[0];
        Image.Plane U = image.getPlanes()[1];
        Image.Plane V = image.getPlanes()[2];

        int Yb = Y.getBuffer().remaining();
        int Ub = U.getBuffer().remaining();
        int Vb = V.getBuffer().remaining();

        byte[] data = new byte[Yb + Ub + Vb];


        Y.getBuffer().get(data, 0, Yb);
        V.getBuffer().get(data, Yb, Vb);
        U.getBuffer().get(data, Yb + Vb, Ub);



        rs = RenderScript.create(context);
        ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));

        Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
        Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);

        Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
        Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);

        final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);

        in.copyFromUnchecked(data);

        yuvToRgbIntrinsic.setInput(in);
        yuvToRgbIntrinsic.forEach(out);
        out.copyTo(bmpout);
        image.close();
        return bmpout ;
    }

日志打印:

从下面日志可以看到,1920 * 1080的分辨率下,转换耗时在30 ms左右.

2023-12-25 14:06:27.294 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics end
2023-12-25 14:06:27.311 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics start
2023-12-25 14:06:27.352 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics end
2023-12-25 14:06:27.353 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics start
2023-12-25 14:06:27.371 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics end
2023-12-25 14:06:27.398 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics start
2023-12-25 14:06:27.415 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics end
2023-12-25 14:06:27.435 15912-22157 Camera2BasicFragment    com.android.camera2demo              E  YUV_420_888_toRGBIntrinsics start

扩展:

1、Vulkan

Vulkan在Android使用Compute shader

https://zhuanlan.zhihu.com/p/258130830

https://blog.51cto.com/u_16099335/6861390

2、libyuv

https://github.com/GitLqr/LQRLibyuv

欢迎点击关注,一起见证彼此的成长!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值