前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >探索Camera ImageReader YUV420_888 快速转bitmap argb888的方式

探索Camera ImageReader YUV420_888 快速转bitmap argb888的方式

作者头像
小驰随想录
发布2024-05-27 20:49:28
570
发布2024-05-27 20:49:28
举报
文章被收录于专栏:Android Camera开发Android Camera开发

从 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。

代码语言:javascript
复制
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");
            }
        }
    };
代码语言:javascript
复制
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左右。

代码语言:javascript
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小驰成长圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
GPU 云服务器
GPU 云服务器(Cloud GPU Service,GPU)是提供 GPU 算力的弹性计算服务,具有超强的并行计算能力,作为 IaaS 层的尖兵利器,服务于深度学习训练、科学计算、图形图像处理、视频编解码等场景。腾讯云随时提供触手可得的算力,有效缓解您的计算压力,提升业务效率与竞争力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档