探索Camera 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

作者:小驰,公众号:小驰行动派

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论