近年来,图片高斯模糊备受设计师的青睐,在各大知名APP中,如微信、手机QQ、网易云音乐等等都有对背景高斯图模糊的设计,在Adnroid 中,现在常用的图片高斯模糊技术有三种:RenderScript 、fastBlur、对RenderScript和fastBlur的优化,接下来分别分析各自的优缺点和在项目中该使用哪个解决方案。先上一张效果图:
1,RenderScript
RenderScript是在Android上的高性能运行密集型运算的框架,RenderScript主要用于数据并行计算,尤其对图像处理、摄影分析和计算机视觉特别有用。RenderScript是在Android3.0(API 11)引入的。而Android图片高斯模糊处理,通常也是用这个库来完成。它提供了我们Java层调用的API,实际上是在c/c++ 层来处理的,所以它的效率和性能通常是最高的。要使用RenderScript完成图片高斯模糊只需要以下几步:
(1) 初始化一个RenderScript Context:RenderScript 上下文环境通过create(Context)
方法来创建,它保证RenderScript的使用并且提供一个控制后续所有RenderScript对象(如:ScriptIntrinsicBlur、Allocation等)生命周期的对象。
(2)通过Script至少创建一个Allocation:一个Allocation是提供存储大量可变数据的RenderScript 对象。在内核中,Allocation作为输入和输出,在内核中通过rsGetElementAt_type ()
和rsSetElementAt_type()
方法来访问Allocation当script全局绑定的时候。使用createFromBitmap
和createTyped
来创建Allocation。
(3)创建ScriptIntrinsic:它内置了RenderScript 的一些通用操作,如高斯模糊、扭曲变换、图像混合等等,更多的操作请看ScriptIntrinsic
的子类,本文要用的高斯模糊处理就是用的它的子类ScriptIntrinsicBlur
。
(4)填充数据到Allocations:除了使用方法createFromBitmap
创建的Allocation外,其它的第一次创建时都是填充的空数据。
(5)设置模糊半径:设置一个模糊的半径,其值为 0-25。
(6) 启动内核,调用方法处理:调用forEach 方法模糊处理。
(7) 从Allocation 中拷贝数据:为了能在Java层访问Allocation的数据,用Allocation其中一个copy
方法来拷贝数据。
(8) 销毁RenderScript对象:可以用destroy
方法来销毁RenderScript对象或者让它可以被垃圾回收,destroy 之后,就能在用它控制的RenderScript对象了(比如在销毁了之后,再调用ScriptIntrinsic或者Allocation的方法是要抛异常的)。
以上几个步骤就可以完成的图片的高斯模糊,看一下对应的代码:
private static Bitmap rsBlur(Context context,Bitmap source,int radius){
Bitmap inputBmp = source;
//(1)
RenderScript renderScript = RenderScript.create(context);
Log.i(TAG,"scale size:"+inputBmp.getWidth()+"*"+inputBmp.getHeight());
// Allocate memory for Renderscript to work with
//(2)
final Allocation input = Allocation.createFromBitmap(renderScript,inputBmp);
final Allocation output = Allocation.createTyped(renderScript,input.getType());
//(3)
// Load up an instance of the specific script that we want to use.
ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
//(4)
scriptIntrinsicBlur.setInput(input);
//(5)
// Set the blur radius
scriptIntrinsicBlur.setRadius(radius);
//(6)
// Start the ScriptIntrinisicBlur
scriptIntrinsicBlur.forEach(output);
//(7)
// Copy the output to the blurred bitmap
output.copyTo(inputBmp);
//(8)
renderScript.destroy();
return inputBmp;
}
上面对应的步骤已经用序号标出,代码就十行左右,很简单。这就十Android提供给我们的可以处理图片高斯模糊的库。性能比较好,因为是在c/c++层做的处理。但是它只能在API 17或者更高的版本使用, 看一下文档的说明:
如上图,红框中标记的ScriptIntrinsicBlur 是在API 17加入的,因此低版本的手机是用不了,为了能兼容低版本的手机,我们还得探索其他方案。
RenderScript 兼容包:
所幸的是,Google 为了兼容低版本也可以用RenderScript,加了一个兼容包,android.support.v8.renderscript ,使用support.v8.renderscript
就能兼容到Android 2.3版本(API 9),现在市面上估计没有比2.3版本还低的手机了(4.x 的手机都不多了)。使用兼容包和使用原生的RenderScript完全一样,代码还是上面的代码。只是需要在app 的build.gradle添加如下的代码
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
// 使用support.v8.renderscript
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
}
}
只要添加上面的2行代码就行了。但是有2点需要注意:
注意:
1,Android SDK Tools revision 22.2 or higher(Tools 需要22.2或者更高的版本)
2,Android SDK Build-tools revision 18.1.0 or higher( Build-tools 需要1