Android RenderScript 简单高效实现图片的高斯模糊效果

高斯模糊(Gaussian blur)和毛玻璃效果(亦称磨砂效果),近两年在移动端的UI设计上越来越流行,特别是iOS手机上出现的较多,iOS系统也提供了相应的API帮助开发人员分分钟实现这两个效果。而Android系统则经历了一个漫长的探索过程,对图片的处理,从Java算法到NDK方式实现等,各种摸索层出不穷。

值得欣慰的是,Google终于在API 11中引入了RenderScript,一个强大的图片处理框架,帮助Android开发人员专注于图片处理算法而不是API的调度工作。使用RenderScript进行图片处理,还需要了解RenderScript Intrinsics,一些可以帮助RenderScript快速实现各种图片处理的操作类。比如ScriptIntrinsicBlur,可以简单高效地帮助我们实现高斯模糊效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public Bitmap blurBitmap(Bitmap bitmap){

//Let's create an empty bitmap with the same size of the bitmap we want to blur
Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);

//Instantiate a new Renderscript
RenderScript rs = RenderScript.create(getApplicationContext());

//Create an Intrinsic Blur Script using the Renderscript
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

//Create the Allocations (in/out) with the Renderscript and the in/out bitmaps
Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);

//Set the radius of the blur: 0 < radius <= 25
blurScript.setRadius(25.0f);

//Perform the Renderscript
blurScript.setInput(allIn);
blurScript.forEach(allOut);

//Copy the final bitmap created by the out Allocation to the outBitmap
allOut.copyTo(outBitmap);

//recycle the original bitmap
bitmap.recycle();

//After finishing everything, we destroy the Renderscript.
rs.destroy();

return outBitmap;

}

通过设置模糊半径(radius)的大小来控制图片的清晰度,简短的几行代码轻松实现图片的高斯模糊处理,我们看一下radius等于最大值25时的图片模糊效果:

原图效果:
RenderScript-Blur-Before

高斯模糊:
RenderScript-Blur-After

注意:ScriptIntrinsicBlur的相关方法只支持API 17及以上版本的系统,为了兼容旧版本,Google 提供了android.support.v8.renderscript兼容包,使用时引入该兼容包包下的相关类即可:

1
2
3
4
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptIntrinsicBlur;

注意:android.support.v8.renderscript兼容包的使用不需要在app/build.gradle文件中额外添加依赖,而是在defaultConfig配置中添加如下两行代码:

1
2
3
4
5
defaultConfig {
......
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}

在设计上巧妙地运用高斯模糊往往能达到出乎意料的体验效果,比如大神daimajia就利用RenderScript和NineOldAndroids做了一个比较有创意的UI交互,开源库为:AndroidViewHover,效果如下,感兴趣的同学可以一探究竟:

daimajia-AndroidViewHover.gif

关于Android平台的图片模糊处理,在GitHub上有一些较为优秀的开源类库,笔者整理了一些,推荐给大家学习使用:

当然,不同类库实现的方式、采取的算法和耗费的时间各有差异,开源项目BlurTestAndroid对这些类库做了一个统计和比较,选择不同尺寸的图片和不同大小的模糊半径,以图表的形式直观地展示各种类库的模糊处理效率:

BlurTestAndroid.jpg