图像模糊处理RenderScript

在Android中,我们可以实现很多很酷的处理图片的效果。在2014年某次会议的讲演《图像的魔力》中,我介绍了其中的一部分。其中的一项技术是如何模糊图像,示例代码是使用RenderScript实现的,因为在Android中没有内置的可使用的简单的API。在这个系列中,我们将着眼于RenderScript模糊技术和JAVA实现模糊功能。我们还将进行一些基准测试,以了解每种方案的运行情况,并探讨获取最佳性能的可行方法。

让我们先从实现一个简单的可以运行的例子开始,使用RenderScript!对于没有使用过RenderScript的开发者来说,这是一个让人心生恐惧的设想,因为RenderScript真的是很难,是不是?是的,的确是。不过它也有一些事情真的很简单,而模糊图像就是其中之一。

对于不熟悉RenderScript的人来说,他是在API11中引入的,并且有一个compat库,提供RenderScript给API8及以后的版本。它本质上是一个面向图形的本地计算框架。RenderScript引擎在运行期会选择最合适的处理器(CPU或者GPU核心,多核处理器间可以分解原子操作)来执行请求的操作。本地语法基于C99,与OpenCL, CUDA, and GLSL的API相似。

如果这听起来很可怕,请稍等一下,因为我们正要简化整个过程。因为它是一个框架,允许我们创建自定义的内核来实现过滤与处理,它内置了不少可以使用的内核,其中的一个允许我们模糊图像。

后面的实例代码基于API17及更高版本开发,我已经决定不使用compat库,因为在本文写作的时候,Android Studio还不支持。此外,我们使用的模糊核心在API17后才引入,所以有最小SDK版本为17的需求。

让我们深入到一个简单的例子,这里有一个非常简单的RelativeLayout,包含了一个ImageView,上层还有个TextView:

<?xmlversion="1.0"encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image"
        android:src="@drawable/broadstairs"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="matrix"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        android:layout_centerHorizontal="true"
        android:textColor="<a href="http://www.jobbole.com/members/android/"rel="nofollow">@android</a>:color/white"
        android:layout_marginTop="300dp"
        android:textStyle="bold"
        android:textSize="48sp"/>
</RelativeLayout>

我们想要做的效果是模糊ImageView内位于TextView显示区域的图像,有效的模糊ImageView后的区域。我们最终使用的技术是拿到位于TextView区域的图像副本进行模糊,然后再将模糊后的副本设定为TextView的背景。

我刻意的设计了这种布局,使图像显示实际大小,并从显示屏的左上方开始。这样让随后的位置计算简单些,而且这里讨论的是模糊技术而不是图像定位的数学算法。尝试设定ImageView的属性android:scaleType=”center”,就会发现定位出现错乱。

此处有一个方法,它有3个参数,一个位图(已在ImageView里获得),一个视图(这是我们的TextView,但是该技术适用于任意的视图类型,所以我们将在方法中进行支持),以及一个半径用来控制模糊的程度。

private void blur(Bitmap bkg, View view, floatradius) {
    Bitmap overlay = Bitmap.createBitmap(
        view.getMeasuredWidth(),
        view.getMeasuredHeight(),
        Bitmap.Config.ARGB_8888);
    Canvas canvas =new Canvas(overlay);
    canvas.drawBitmap(bkg, -view.getLeft(),
        -view.getTop(),null);
    RenderScript rs = RenderScript.create(this);
    Allocation overlayAlloc = Allocation.createFromBitmap(
        rs, overlay);
    ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(
        rs, overlayAlloc.getElement());
    blur.setInput(overlayAlloc);
    blur.setRadius(radius);
    blur.forEach(overlayAlloc);
    overlayAlloc.copyTo(overlay);
    view.setBackground(newBitmapDrawable(
        getResources(), overlay));
    rs.destroy();
}

我们要做的第一件事是创建一个新的位图对象,用来保存想要模糊的图像区域的副本。它的大小将会是我们视图的尺寸(2-5行)。

现在我们将空的位图包装到画布中,我们可以在上面绘图(7行)。

接下来的步骤我称为”缓存剪切”,我们拷贝位图中的处于视图显示区域内的那部分图像(9-10行)。

接下来我们必须做的事情是构建一个RenderScript对象上下文,在其中我们执行模糊操作(12行)。

RenderScript是一个本地环境,它在自己的内存空间内运行,所以我们不能简单的传递位图引用,我们需要在JAVA和RenderScript内存区域进行序列化。这使用了一个分配实例来完成,这是在RenderScript内存区域中创建和引用对象的方式,为我们的位图创建一个分配会将位图的内容拷贝的分配区域中(14-15行)。

现在我们创建一个 ScriptIntrinsicBlur实例,它创建合适的RenderScript模糊脚本,并且是脚本对象的Java接口,它让我们能够控制它。(17-18行)。

脚本的输入定义了我们需要执行模糊的位图源(20行)。

现在我们设置半径来控制模糊强度(22行)。

forEach方法执行模糊操作,参数代表了结果的输出位置。我们将它写回源分配地址以减少创建的对象数量(24行)。

现在模糊完成了,但是我们必须把模糊后的图像拷贝回JAVA内存区域(26行)。

最后将模糊后的位图包装到BitmapDrawable内,并设置为视图的背景(28-29行)。

我们已经使用完RenderScript上下文,清理掉。这样做也将自动删除我们的分配(31行)。

这就是我们完整的基本模糊逻辑,但目前还不清楚什么地方和什么时候我们需要调用此方法。不幸的是关于这个问题不能简单的进行回答,所以我们将在接下来的文章中讨论。

平时我喜欢每篇文章都发布相关工作代码,但是在本例中,我们还没达到有一个可运行的完整的端到端的示例的程度。我保证在接下来的文章中进行调整。

时间: 2024-09-15 07:59:13

图像模糊处理RenderScript的相关文章

matlab-数字图像处理问题,两直方图相同的图像模糊后直方图还相同吗

问题描述 数字图像处理问题,两直方图相同的图像模糊后直方图还相同吗 1C 两幅不同的图像具有相同的直方图,假设每一幅图像都用一个3×3的均值模版来进行模糊处理,则处理后的直方图还相同吗?解释原因并画出两个直方图. 第3.14题,跪求 解决方案 这个不一定,比如100100100100100100100100100和111000000111000000111000000灰度直方图相同但是模糊以后肯定不同 解决方案二: 但是自然的,非人为构造的图,大体上是相同的. 解决方案三: Win8 Metro

使用RenderScript实现高斯模糊(毛玻璃/磨砂)效果

前言 逛instagram的时候,偶然发现,instagram的对话框设计的很有意思,如下图:   它的dialog的背景竟然是毛玻璃效果的,在我看来真漂亮,恩,对话框和迪丽热巴都漂亮.看到这么好的效果,当然就要开始搞事情了,自己动手实现差不多的效果.最终的实现效果如下图:   分别实现了对话框背景的虚化和手动调节虚化程度. 实现方法对比 最开始想要实现毛玻璃效果时,我是一脸懵逼的,不知道如何下手.幸亏,有万能的Google.搜索之后发现常见的实现方法有4种,分别是: RenderScript

Android RenderScript高斯模糊_Android

看代码的时候,看到了其中有.rs结尾的文件,不是很明白,还有RenderScript类,看的一脸蒙蔽,不知所云,然后百度了一下,收货还真不少,这东西在图形处理这块用处挺大的. 今天先说说ScriptIntrinsicBlur,这个类不需要定义rs文件,从这个Intrinsic单词可以看的出来,它是API17以后内置的类,专门用来处理图像的,让图片变模糊. public static Bitmap blurBitmap(Bitmap bitmap, float radius, Context co

Android RenderScript实现高斯模糊_Android

昨天看了下RenderScript的官方文档,发现RenderScript这厮有点牛逼.无意中发现ScriptIntrinsic这个抽象类,有些很有用的子类.其中有个子类叫ScriptIntrinsicBlur类,大致就是将图片实现高斯模糊. ScriptIntrinsic的申明: ScriptIntrinsicBlur类的申明: 加上结合着看了下SDK中的samples,自己写了个高斯模糊. ( sample的具体位置为: SDK目录/samples/android-19/renderscri

Android利用RenderScript实现毛玻璃模糊效果示例

RenderScript 介绍 在开始之前,先看下 RenderScript 的官方介绍: RenderScript is a framework for running computationally intensive tasks at high performance on Android. RenderScript is primarily oriented for use with data-parallel computation, although serial workloads

Android RenderScript高斯模糊

看代码的时候,看到了其中有.rs结尾的文件,不是很明白,还有RenderScript类,看的一脸蒙蔽,不知所云,然后百度了一下,收货还真不少,这东西在图形处理这块用处挺大的. 今天先说说ScriptIntrinsicBlur,这个类不需要定义rs文件,从这个Intrinsic单词可以看的出来,它是API17以后内置的类,专门用来处理图像的,让图片变模糊. public static Bitmap blurBitmap(Bitmap bitmap, float radius, Context co

JavaScript实现的图像模糊算法代码分享_javascript技巧

项目中需要用到HTML5模糊图像,以前用GDI,GDI+中都有现成的组件来实现,HTML5中如何实现?1.createImageData()2.getImageData()3.putImageData()以上3个函数即可实现,用法和奥义,自己百度吧,我就不重复叙述了,没多大的意义. 以下是实现模糊算法的JS,其实还有种2B级算法就是分布矩阵,这样效率提高很多倍,不过效果很差,羽化的效果不强.实现代码: 复制代码 代码如下: var mul_table = [        512,512,456

Android模糊图像

在Android中,我们可以实现很多很酷的处理图片的效果.在2014年某次会议的讲演<图像的魔力>中,我介绍了其中的一部分.其中的一项技术是如何模糊图像,示例代码是使用RenderScript实现的,因为在Android中没有内置的可使用的简单的API.在这个系列中,我们将着眼于RenderScript模糊技术和JAVA实现模糊功能.我们还将进行一些基准测试,以了解每种方案的运行情况,并探讨获取最佳性能的可行方法. 让我们先从实现一个简单的可以运行的例子开始,使用RenderScript!对于

图像处理------移动模糊

卷积模糊或者卷积平滑滤波,可以消除图像噪声,也可以产生一些常见的图像模糊特效,但 是移动模糊特效也是基于卷积,相比于Box Blur, Gaussian Blur的算法,移动模糊只需要完成 一次的一维卷积,所不同的是一维卷积的完成,要基于一定的角度,而不是只是在水平和垂 直两个方向上.移动模糊的一维卷积要考虑一下三个因素:                      a. 操作数的多少 - 即距离(Distance)                      b.一维操作数在像素数组中的移动方向