现在图片模糊化已经是很常用的,有多背景图片都选择了磨砂效果,感觉也是将图片模糊化了.
一般来说,考虑到效率,渲染一张图片最好的方法是使用OpenGL,其次是使用C++/C,使用Java代码是最慢的。但是Android推出RenderScript之后,我们就有了新的选择,测试表明,使用RenderScript的渲染效率和使用C/C++不相上下,但是使用RenderScript却比使用JNI简单地多!同时,Android团队提供了RenderScript的支持库,使得在低版本的Android平台上也能使用。
不过在使用RenderScript之前,对于模糊一张图片,需要注意的是,我们应该尽量不要使用原尺寸分辨率的图片,最好将图片缩小比例,这小渲染的效率要高一些。
那接下来我们就来通过RenderScript实现将ImageView上的图片模糊化吧
首先定义一个工具类BlurBitmap , 并提供一个方法来用于模糊化图片 :
public class BlurBitmap {
/**
* 图片缩放比例
*/
private static final float BITMAP_SCALE = 0.4f;
/**
* 最大模糊度(在0.0到25.0之间)
*/
private static final float BLUR_RADIUS = 25f;
/**
* 模糊图片的具体方法
*
* @param context 上下文对象
* @param image 需要模糊的图片
* @return 模糊处理后的图片
*/
public static Bitmap blur(Context context, Bitmap image) {
// 计算图片缩小后的长宽
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
// 将缩小后的图片做为预渲染的图片。
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
// 创建一张渲染后的输出图片。
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// 创建RenderScript内核对象
RenderScript rs = RenderScript.create(context);
// 创建一个模糊效果的RenderScript的工具对象
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
// 设置渲染的模糊程度, 25f是最大模糊度
blurScript.setRadius(BLUR_RADIUS);
// 设置blurScript对象的输入内存
blurScript.setInput(tmpIn);
// 将输出数据保存到输出内存中
blurScript.forEach(tmpOut);
// 将数据填充到Allocation中
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
第二步 : 在app的gradle文件中添加下面的支持
defaultConfig {
......
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
}
第三步 : 这个时候也许BlurBitmap 中有些方法也许还在报错 , 别怕,将光标放在报错的地方,会得到提示说要求最低sdk版本是17,那就改成17就是了。
第四步:由于我们的BlurBitmap .blur()方法接收的bitmap对象,而我们图片是放在drawable下的,所以我们有必要将drawable的资源图片转化为Bitmap对象,使用BiamapFactory.decodeResource()方法就能轻松的实现了,代码如下:
Bitmap bmp= BitmapFactory.decodeResource(getResources(),R.drawable.hy);
最后:将图片模糊化并设置在ImageView上展示:
Bitmap bBitmap=BlurBitmap.blur(MainActivity.this,bmp);
imageView.setImageBitmap(bBitmap);
将图片模糊化并设置在ImageView上就完成了,总觉得还是缺点个什么,能不能动态地改变图片的模糊度呢?
经过实验证明:渲染一张500*700分辨率的PNG格式图片,在我的Pro 6手机上,仍然需要50ms左右的时间,显然如果使用上面的代码进行实时动态渲染的话,会造成界面严重的卡顿。
既然如此,那今天就到这里吧。