Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊

文章目录

  • Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊
      • 使用 RenderEffect 模糊
      • 使用 Vukan 模糊
      • 使用 GLSL 模糊
      • RS、Vukan、RenderEffect、GLSL 效率对比

Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊

本文首发地址 https://blog.csdn.net/CSqingchen/article/details/134656140
最新更新地址 https://gitee.com/chenjim/chenjimblog

通过 Android Bitmap 使用 ScriptIntrinsicBlur、Toolkit 实现模糊,我们已经知道两种实现模糊方法。
本文主要讲解另外几种高效实现Bitmap模糊的方法。

使用 RenderEffect 模糊

RenderEffect 是 Android 中一种用于实现图像特效的类,**最低 API 要求 31 ** 。
它允许开发者在不修改原始图像数据的情况下,对图像进行各种处理,例如模糊、光晕、阴影等
对 Bitmap 模糊及注释代码如下

fun blur(bitmap:Bitmap, radius: Float, outputIndex: Int): Bitmap {// 配置跟 bitmap 同样大小的 ImageReaderval imageReader = ImageReader.newInstance(bitmap.width, bitmap.height,PixelFormat.RGBA_8888, numberOfOutputImages,HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT)val renderNode = RenderNode("RenderEffect")val hardwareRenderer = HardwareRenderer()// 将 ImageReader 的surface 设置到 HardwareRenderer 中hardwareRenderer.setSurface(imageReader.surface)hardwareRenderer.setContentRoot(renderNode)renderNode.setPosition(0, 0, imageReader.width, imageReader.height)// 使用 RenderEffect 配置模糊效果,并设置到 RenderNode 中。  val blurRenderEffect = RenderEffect.createBlurEffect(radius, radius,Shader.TileMode.MIRROR)renderNode.setRenderEffect(renderEffect)// 通过 RenderNode 的 RenderCanvas 绘制 Bitmap。   val renderCanvas = renderNode.beginRecording()renderCanvas.drawBitmap(bitmap, 0f, 0f, null)renderNode.endRecording()// 通过 HardwareRenderer 创建 Render 异步请求。   hardwareRenderer.createRenderRequest().setWaitForPresent(true).syncAndDraw()// 通过 ImageReader 获取模糊后的 Image 。val image = imageReader.acquireNextImage() ?: throw RuntimeException("No Image")// 将 Image 的 HardwareBuffer 包装为 Bitmap , 也就是模糊后的。   val hardwareBuffer = image.hardwareBuffer ?: throw RuntimeException("No HardwareBuffer")val bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, null)?: throw RuntimeException("Create Bitmap Failed")hardwareBuffer.close()image.close()return bitmap
}

完整实例参考 RenderEffectImageProcessor.kt
还可以通过设置 RenderEffect 的其他属性,如 setColorFilter( )方法,为模糊后的 Bitmap 添加颜色滤镜。

使用 Vukan 模糊

Vulkan 是一种低开销、跨平台的 API,用于高性能 3D 图形。
Android平台包含 Khronos Group 的 Vulkan API规范的特定实现。
使用 Vukan 模糊的核心代码如下,可参考 ImageProcessor.cpp

bool ImageProcessor::blur(float radius, int outputIndex) {RET_CHECK(1.0f <= radius && radius <= 25.0f);//高斯模糊配置,在后文 GLSL 同样 适用constexpr float e = 2.718281828459045f;constexpr float pi = 3.1415926535897932f;float sigma = 0.4f * radius + 0.6f;float coeff1 = 1.0f / (std::sqrtf(2.0f * pi) * sigma);float coeff2 = -1.0f / (2.0f * sigma * sigma);int32_t iRadius = static_cast<int>(std::ceilf(radius));float normalizeFactor = 0.0f;for (int r = -iRadius; r <= iRadius; r++) {const float value = coeff1 * std::powf(e, coeff2 * static_cast<float>(r * r));mBlurData.kernel[r + iRadius] = value;normalizeFactor += value;}normalizeFactor = 1.0f / normalizeFactor;for (int r = -iRadius; r <= iRadius; r++) {mBlurData.kernel[r + iRadius] *= normalizeFactor;}RET_CHECK(mBlurUniformBuffer->copyFrom(&mBlurData));// 应用两阶段模糊算法:一个水平模糊核,然后是一个垂直模糊核。// 比单遍应用一个2D模糊滤镜更高效。// 两遍模糊算法有两个核,每个核的时间复杂度为O(半径),// 而单遍模糊算法只有一个核,但时间复杂度为O(半径^2)。auto cmd = mCommandBuffer->handle();RET_CHECK(beginOneTimeCommandBuffer(cmd));// 临时映像在第一遍中用作输出存储映像mTempImage->recordLayoutTransitionBarrier(cmd, VK_IMAGE_LAYOUT_GENERAL, /*preserveData=*/false);// 水平方向高斯模糊mBlurHorizontalPipeline->recordComputeCommands(cmd, &iRadius, *mInputImage, *mTempImage,mBlurUniformBuffer.get());// 临时图像在第二遍中用作输入采样图像,// 过渡图像用作输出存储映像。mTempImage->recordLayoutTransitionBarrier(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);mStagingOutputImage->recordLayoutTransitionBarrier(cmd, VK_IMAGE_LAYOUT_GENERAL,/*preserveData=*/false);// 数值方向高斯模糊mBlurVerticalPipeline->recordComputeCommands(cmd, &iRadius, *mTempImage, *mStagingOutputImage,mBlurUniformBuffer.get());// 准备将图像从过渡图像复制到输出图像。mStagingOutputImage->recordLayoutTransitionBarrier(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);// 复制暂存图像到输出图像。recordImageCopyingCommand(cmd, *mStagingOutputImage, *mOutputImages[outputIndex]);// 提交到队列。RET_CHECK(endAndSubmitCommandBuffer(cmd, mContext->queue()));return true;
}

VulkanContext.cpp 主要是一些初始化

VulkanResources.cpp 主要是 Buffer 和 Image 的一些封装方法

上层接口参见 VulkanImageProcessor.kt

使用 GLSL 模糊

主要流程:

  • 将输入 Bitmap 转为纹理
    GLES31.glTexStorage2D(GLES31.GL_TEXTURE_2D, 1, GLES31.GL_RGBA8, mInputImage.width, mInputImage.height )
    GLUtils.texImage2D(GLES31.GL_TEXTURE_2D, 0, mInputImage, 0)
  • 通过 OpenGL 处理纹理,同样有水平、竖直模糊,即 mBlurHorizontalProgram 和 mBlurVerticalProgram
  • 将纹理转换为 Bitmap ,即 copyPixelsToHardwareBuffer ,这里也是耗时最多的

完整实例参考 GLSLImageProcessor.kt

libVkLayer_khronos_validation.so 主要是调试用,
ImageProcessor::create(/*enableDebug=*/false, assetManager) 传入 false 可以不需要
可以在以下地址下载新版本
https://github.com/KhronosGroup/Vulkan-ValidationLayers

RS、Vukan、RenderEffect、GLSL 效率对比

上文完整源码及对比示例地址
https://gitee.com/chenjim/android-blur/blob/blur/RenderScriptMigrationSample

他们之间效率对比结果如下

虽然 GLSL 看起来会差一些,主要是因为 openGL 纹理转 Bitmap 耗时较大。
如果纯GL场景使用,跟 Vukan 和 RenderEffect 相差无几。


以上就是Android 使用Vukan、RenderEffect、GLSL实现模糊的介绍,希望对你有所帮助。
如果你在使用过程遇到问题,可以留言讨论。
如果你觉得本文写的还不错,欢迎点赞收藏。


相关文章
Android Bitmap 使用ScriptIntrinsicBlur、Toolkit 实现模糊
Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/188670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运算放大器和常见运放电路

关于运算放大器 运算放大器(Operational Amplifier), 简称运放, 是一种直流耦合, 差模输入, 单端输出(Differential-in, single-ended output)的高增益电压放大器件. 运放能产生一个比输入端电势差大数十万倍的输出电势. 因为刚发明时主要用于加减法等运算电路中, 因而得名运算…

LLM算法工程师面试题总结

一、请简述对大模型的基本原理和架构的理解。 大型语言模型如GPT&#xff08;Generative Pre-trained Transformer&#xff09;系列是基于自注意力机制的深度学习模型&#xff0c;主要用于处理和生成人类语言。下面简要概述了它们的一些基本原理和架构特点&#xff1a; 基本原…

线上问题整理-ConcurrentModificationException异常

项目场景&#xff1a; 商品改价&#xff1a;商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象 问题描述 商品改价中通过多线程批量处理经过 Lists.partition拆分的集合对象&#xff0c;发现偶尔会报 java.util.ConcurrentModificationException: nullat jav…

用element-ui进行简单的商品管理

安装element-ui 项目的控制台输入npm i element-ui -S main.js import ElementUI from element-ui;//引入element-ui模块 import element-ui/lib/theme-chalk/index.css;//引入element-ui的css样式 Vue.use(ElementUI);//使用ElementUI 商品管理组件 <template><…

使用Redis实现分布式锁

说明&#xff1a;在多线程情况下&#xff0c;我们需要用到锁来控制线程对资源的访问&#xff0c;当在多线程分布式的情况下&#xff0c;如果使用synchronized (this)&#xff0c;这会在每台服务器实例上都生成一个锁对象&#xff0c;而这个锁只会对当前实例生效&#xff0c;无法…

【数字图像处理】边缘检测

边缘检测是一种图像处理技术&#xff0c;用于在图像中识别和提取物体边缘的信息&#xff0c;广泛应用于计算机视觉和图像分析领域。本文主要介绍数字图像边缘检测的基本原理&#xff0c;并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。 目录 1 边缘检测原理 2 FPGA 布署…

【工具分享】| 阅读论文神器 使用技巧 AI润色 AI翻译

文章目录 1 使用技巧1.1 功能一 即时翻译1.2 功能二 文献跳转1.3 功能三 多设备阅读1.4 功能四 小组讨论笔记共享1.5 功能五 个人文献管理 2 其他功能 超级喜欢Readpaper这一款论文阅读软件&#xff0c;吹爆他哈哈 为什么&#xff1f; 当然是他可以解决我们传统阅读论文的种种…

数据库范式1NF-4NF

码和属性 字段是对内而言的&#xff0c;private的 属性是对外而言的&#xff0c;public的 用Java中的类比喻就是一个对像里面定义了很多字段&#xff0c;一般情况下每个字段都有一组对应的getter&setter方法&#xff0c;注意到了吗&#xff0c;字段一般用private修饰&#…

HarmonyOs 4 (一) 认识HarmonyOs

目录 一 HarmonyOs 背景1.1 发展时间线1.2 背景分析1.2.1 新场景1.2.2 新挑战1.2.3 鸿蒙生态迎接挑战 二 HarmonyOS简介2.1 OpenHarmony2.2 HarmonyOS Connect2.3 HarmonyOS Next**2.4 ArkTS &#xff08;重点掌握&#xff09;****2.5 ArkUI** 三 鸿蒙生态应用核心技术理念**3.…

探索APP自动化测试工具的重要作用是什么?

随着移动应用市场的蓬勃发展&#xff0c;保障应用程序的质量和性能成为开发团队至关重要的任务。在这个背景下&#xff0c;APP自动化测试工具崭露头角&#xff0c;成为提高开发效率、减少错误率的关键工具。本文将探讨APP自动化测试工具的用途&#xff0c;以及它们在移动应用开…

mongoDB非关系型数据库学习记录

一、简介 1.1Mongodb是什么 MongoDB是一个基于分布式文件存储的数据库,官方地址https://www.mongodb.com/ 1.2数据库是什么 数据库(DataBase)是按照数据结构来组织、存储和管理数据的应用程序 1.3数据库的作用 数据库的主要作用就是管理数据,对数据进行增©、删(d)、…

大语言模型(LLMs)在 Amazon SageMaker 上的动手实践(一)

本期文章&#xff0c;我们将通过三个动手实验从浅到深地解读和演示大语言模型&#xff08;LLMs&#xff09;&#xff0c;如何结合 Amazon SageMaker 的模型部署、模型编译优化、模型分布式训练等。 实验一&#xff1a;使用 Amazon SageMaker 构建基于开源 GPT-J 模型的对话机器…

C语言错误处理之 “strerror和perror函数以及断言处理方式”

目录 前言 perror函数 strerror函数 断言处理方式 前言 在错误处理一中&#xff0c;我们解释了C语言三种处理方式中的错误号处理方式&#xff0c;这一篇我们在基于上一篇的基础上加入了strerror函数与perror函数&#xff0c;以及断言处理方式的内容...... perror函数 包…

VSCode下载安装教程+安装插件

一、vscode下载安装 1.打开 官网&#xff1a;https://code.visualstudio.com/Download 2.选择跟你电脑相对应的版本下载&#xff0c;我是win10&#xff0c;所以选择如下&#xff1a; 3.下载到你想要保存的目录下 4.下载完成后打开目录&#xff0c;双击安装包 5. 同意&#xff…

使用YOLOv8训练自己的数据集

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 拉取项目 git clone https://github.com/ultralytics/ultralytics安装依赖 cd ultralytics pip install -r requirement.txt pip instal…

【android开发-10】android中四种布局详细介绍

在Android开发中&#xff0c;常见的四种布局分别是&#xff1a;线性布局&#xff08;LinearLayout&#xff09;、相对布局&#xff08;RelativeLayout&#xff09;、帧布局&#xff08;FrameLayout&#xff09;和绝对布局&#xff08;AbsoluteLayout&#xff09;。 注意&#…

第16届中国R会议暨2023X-AGI大会开幕,和鲸科技分享ModelOps在数据科学平台中的实践与应用

11月25日&#xff0c;第 16 届中国 R 会议暨 2023 X-AGI 大会在在中国人民大学逸夫会堂拉开帷幕&#xff0c;本次会议由中国人民大学统计学院、中国人民大学应用统计科学研究中心、统计之都、原灵科技和中国商业统计学会人工智能分会&#xff08;筹&#xff09;主办&#xff0c…

React项目使用NProgress作为加载进度条

React项目使用NProgress作为加载进度条 0、效果1、react安装依赖2、使用3.进度条颜色设置 文档参考&#xff1a;https://zhuanlan.zhihu.com/p/616245086?utm_id0 0、效果 如下&#xff0c;可全局在页面顶部有一条进度条 1、react安装依赖 yarn add nprogress通过以上安装…

pytest自动化框架之allure测试报告的用例描述设置

allure测试报告的用例描述相关方法&#xff1b;如下图 allure标记用例级别severity 在做自动化测试的过程中&#xff0c;测试用例越来越多的时候&#xff0c;如果执行一轮测试发现了几个测试不通过&#xff0c;我们也希望能快速统计出缺陷的等级。 pytest结合allure框架可以对…

YOLOv5项目实战(5)— 算法模型优化和服务器部署

前言:Hello大家好,我是小哥谈。近期,作者所负责项目中的算法模型检测存在很多误报情况,为了减少这种误报情况,作者一直在不断优化算法模型。鉴于此,本节课就给大家详细介绍一下实际工作场景中如何去优化算法模型和进行部署,另外为了方便大家进行模型训练,作者在文章中提…